So this is for an aim-down sight motion in a FPS game. When the player right clicks, this coroutine is fired up which should move the player's right hand from its "idle" position to its "aiming" position. Once the aiming position is reached, hitbox is activated, and an animation plays.
public float ChargeTime;
public Vector3 TargetPosition;
public override IEnumerator Attack(PlayerController player)
{
float elapsedTime = 0f;
Vector3 currentPos = player.RightHand.transform.localPosition;
while (elapsedTime < ChargeTime)
{
elapsedTime = Time.deltaTime;
player.RightHand.transform.localPosition = Vector3.Lerp(currentPos, TargetPosition, (elapsedTime / ChargeTime));
yield return null;
}
player.RightHand.transform.localPosition = TargetPosition;
player.Hitbox.SetActive(true);
player.RightHandAnimator.SetBool("IsHolding", true);
yield return null;
}
I've been going over and over this code and everything should be working as intended. Debug.Logs will show me I've reached this code exactly once, that I'm looping through this while() function properly, that the t variable of the Lerp does increase properly from 0 to 1, and that the hitbox properly triggers at the end of while()... but the hand simply refuses to move.
I've tripled and quadrupled checked that the RightHand variable is indeed referencing the proper object, and that no other code ever interferes (there is nothing else that makes that specific object move).
Am I not understanding how Vector3.Lerp works? What am I missing?
Thanks!
EDIT: The "override" is because this class derives from "Weapon" which has a virtual Attack coroutine, which gets overriden by different types of Weapon subclasses.
CodePudding user response:
What actually happens? Does the hand not move at all? Your code looks ok to me. Does the hand move at the end of the loop at this line..?
player.RightHand.transform.localPosition = TargetPosition;
If not then, the problem is that the field TargetPosition is wrong. You can ignore the lerp and just try and get that one line working properly, and once it is, your lerp should also work fine.
You could try changing it from simply from a public Vector3 to a Transform and drag a reference to a blank gameobject into it, and use the transform.position field of it in the lerp (the gameobject will be at the position you want the hand to goto) That would make more sense to me, but maybe not for your game. I dunno.
CodePudding user response:
Looks to me like there is an Animator
on your player that affects the right hand position - at least player.RightHandAnimator
leads me to that thought ;)
The Animator
is one of the last things to be executed within a frame and as soon as it holds any keyframe in any state on the player.RightHand.transform.localPosition
it will always overrule whatever changes you make in code!
you could in the meantime turn it off and do e.g.
public override IEnumerator Attack(PlayerController player)
{
player.RightHandAnimator.enabled = false;
var rightHand = player.RightHand.transform;
var currentPos = rightHand.localPosition;
for(var elapsedTime = 0f; elapsedTime < ChargeTime; elapsedTime = Time.deltaTime)
{
rightHand.localPosition = Vector3.Lerp(currentPos, TargetPosition, elapsedTime / ChargeTime);
yield return null;
}
rightHand.localPosition = TargetPosition;
player.Hitbox.SetActive(true);
player.RightHandAnimator.enabled = true;
player.RightHandAnimator.SetBool("IsHolding", true);
}