简体   繁体   中英

transform.position teleporting. Not smoothly moving

Simple question but hard time finding an answer.

I have a hook mechanic where on the press of key.B, a hook will fire for 5 seconds then should come back.

This code is working fine, just that when the code allocated to recall the object, it does not comeback smoothly, it teleports. Here is the code, the problem-specific line in BOLD

public class Hook : MonoBehaviour
{ //Remember Couroutine is pretty much update()

public Transform Target;
private float Thrust; // Int for motion
public Rigidbody rb;
public float HookTravelTime; //Define float for seconds
bool isHookActive = false;  //Are we currently moving?
public float timeHookTraveling = 0f;




// Use this for initialization
void Start()
{
    Thrust = 75f;
    rb = GetComponent<Rigidbody>();
    float walkspeed = Thrust * Time.deltaTime;
}

void OnCollisionEnter(Collision col)
{
    if (col.gameObject.name == "mob")
    {
        Destroy(col.gameObject);
        print("Other code negated");
        rb.velocity = Vector3.zero;
        transform.position = Vector3.MoveTowards(transform.position, Target.position, Thrust);
        isHookActive = false;
        timeHookTraveling = 0f;
    }
}


void ThrowHook()
{

    if (Input.GetKeyDown(KeyCode.B))
    {
        isHookActive = true;
        rb.AddForce(Vector3.forward * Thrust);
    }
    if (isHookActive )
        {
            if (timeHookTraveling >= HookTravelTime) //if the hook traveled for more than hookTravelTime(5 seconds in your case)
            {

            print("hehemeth");
            rb.velocity = Vector3.zero; //negate addforce from before
          **HERE**  transform.position = Vector3.MoveTowards(transform.position, Target.position, Thrust);
            isHookActive = false;//reset this bool so your Update will not check this script until you don't activate it in your ThrowHook
            timeHookTraveling = 0f;//reset the travel time for your next hook activation
        }

            else//if you havent hit 5 keep increasing
            {
                timeHookTraveling += Time.deltaTime;//increase your travel time by last frame's time
            }
        }
    }



// Update is called once per frame
void Update()
    {
    ThrowHook();
    }


}

What am I doing wrong? It should work as intended, right?

Vector3.MoveTowards is needed to be run everyframe, that's why I mentioned * Time.deltaTime in comment.

At 5s, rb's velocity becomes zero and isHookActive becomes false, and thus Vector3.MoveTowards is not called everyframe.

if (Input.GetKeyDown(KeyCode.B))
{
    isHookActive = true;
    rb.AddForce(Vector3.forward * Thrust);
}
if (isHookActive )
{
    if (timeHookTraveling >= HookTravelTime) //if the hook traveled for more than hookTravelTime(5 seconds in your case)
    {

        print("hehemeth");
        rb.velocity = Vector3.zero; //negate addforce from before
        isHookActive = false;//reset this bool so your Update will not check this script until you don't activate it in your ThrowHook
        timeHookTraveling = 0f;//reset the travel time for your next hook activation
    }

    else//if you havent hit 5 keep increasing
    {
        timeHookTraveling += Time.deltaTime;//increase your travel time by last frame's time
    }
}

else if (!isHookActive && transform.position != Target.position)
{
    transform.position = Vector3.MoveTowards(transform.position, Target.position, Thrust * Time.deltaTime);
}

And a even better way is putting

if (Input.GetKeyDown(KeyCode.B))
{
    isHookActive = true;
    rb.AddForce(Vector3.forward * Thrust);
}

into FixedUpdate() but not Update() while

if (isHookActive )
{... }

remains in Update() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM