3
votes

I have a side scrolling 2D game. The player (named Default) is a talking bird with all its limbs, One of the moving limbs is its eyeball (named pupil) and it has a script named EyeController.

enter image description here

What I'm trying to do is:

  • case 1: Bird should stare at a target transform and follow it with eyes. (this is done in the code in EyeController script. you can find it at the end of my question)
  • case 2: When I set a trigger in Bird's animator it starts the eyeballing animation and there is another trigger to go to default animation. (see the image below, two arrows coming out of Any State, so the triggers can change the animation anytime)

Problem is: Case 1 only works if no animation is playing. It stops following with eyes as soon as an animation starts.

While Case 2 always works and somehow prevents pupil to be changed from the code.

I want the code to override the animation.

Bird Animator structure:

enter image description here

Player has an animation with 3 layer.

  1. Base Layer is additive and animates wings.
  2. Mouth is override with weight 1 and animates talking (mouth and pupil and eyebrow).
  3. Leg is override with weight 1 and has nothing in it

as you see below the pupil.position is animated in Default Talking and Default Eyeballing states in Mouth layer.

Not Talking state (the default state in Mouth layer, its animation isn't shown here) has an empty animation.

enter image description here

What I did:

I turned off Write Defaults on all animations. I know it resets animated values animator-wide.

When some triggers are set, the animation works and the pupil animates correctly; however when I change pupil.localPosition in script, it does NOT change the localPosition of the pupil.

part of EyeController script:

//sight controller calls this method in its FixedUpdate
public void LookAt(Vector3 direction)
{
    //transform.localPosition = direction;
    transform.localPosition = new Vector3(1, 1, 0);//just to make sure direction isn't 0,0,0

    UnityEngine.Debug.Log("change!");
}

//I tried Update() : same results
void FixedUpdate()
{
    //When I read localPosition it's always 0,0,0
    UnityEngine.Debug.Log(transform.localPosition);
}

output:

enter image description here

I've been struggling with this issue for weeks and cannot find a way to make it work both ways. If I delete pupil animations, I can animate it with code but I need the animation too as it is a complicated animation.

1

1 Answers

5
votes

Have you tried using LateUpdate() ? If I remember correctly the execution order is something like Update() > FixedUpdate() > Animation > LateUpdate() > Rendering.

Otherwise you could go for manually driven Animations using AnimationClip.SampleAnimation but it would be quite heavy :)