Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by LatvianMan · May 23 at 01:52 PM · movement scriptnpc

,How to make the npc move smoothly instead of teleporting?

I have the zombie(npc) turn to a random direction and move a random number of units in that direction, but whatever I have tried so far just makes it teleport to that position instead of moving to it.

Here is the code:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class ZombieScript : MonoBehaviour {

  public float speed = 1f;
  private float lookDirection;
  private float moveDistance;
  public Vector3 movement;
  public float timer = 0f;
  private float timerSpeed = 1f;
  public float timeToMove = 10f;
  public GameObject zombie;

  void Start()
  {
      lookDirection = Random.Range(-180f, 180f);
      moveDistance = Random.Range(5f, 10f);
  }
 
  void Update()
  {
      timer += Time.deltaTime * timerSpeed;
      if (timer >= timeToMove)
      {
          Vector3 newRotation = new Vector3(0, transform.rotation.y + lookDirection, 0);
          zombie.transform.eulerAngles = newRotation;
          Vector3 movement = Vector3.forward * moveDistance;
          zombie.transform.Translate(Vector3.forward * moveDistance);
          lookDirection = Random.Range(-180f, 180f);
          moveDistance = Random.Range(5f, 10f);
          timer = 0f;
      }
  }

}

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by jackmw94 · May 24 at 10:12 AM

Since your value for moveDistance is a relatively large distance for a single frame (> 0.1 units moved in ~16ms), this is why it appears to teleport. What we want to do instead is move it a very small fraction of this value over a number of frames, only stopping once it reaches the position it was previously teleporting to.

In your code, the character instantly moves by the distance defined in "moveDistance" whereas what we want to do is do this over a few seconds and therefore keep moving the character by moveDistance * Time.deltaTime * moveSpeed each frame until it's close enough to the target position as defined by moveDistance instead. Note for this explanation I'll mention the word "target" meaning the position that it's moving towards, I DON'T mean an actual target!

So there are currently two things that happen in that update function of yours - we specify a new direction and a new distance, generally setting up the new movements AND we also do the movement itself. Let's split these two up:

 private void SetupNewMovement()
 {
     lookDirection = Random.Range(-180f, 180f);
     Vector3 newRotation = new Vector3(0, transform.rotation.y + lookDirection, 0);
     zombie.transform.eulerAngles = newRotation;
     moveDistance = Random.Range(5f, 10f);
     targetPosition = transform.position + transform.forward * moveDistance;
     timer = 0f;
 }


 private void MoveZombie()
 {
     Vector3 movement = Vector3.forward * moveSpeed * Time.deltaTime;
     zombie.transform.Translate(movement);
 }


and finally, a new function for detecting whether we're at our target yet:

 private bool IsAtMovementTarget()
 {
     // checks whether we are within 10cm from our target - an arbitrary "close to" value
     // this assumes that our movements will be less than 20cm each frame
     return Vector3.Distance(transform.position, targetPosition) < 0.1f; 
 }


Note from these functions there are a couple more member we'll need to define. "moveSpeed" can be public so you can set it to a sensible value in your inspector whereas "targetPosition" can be private as it will be handled entirely by the code.

Now most of this is your own code, with a few rearrangements. Let's change the update function to call it in a slightly different manner so that we only change direction when we reach our target:

 private void Update()
 {
     if (IsAtMovementTarget())
     {
         SetupNewMovement();
     }
     MoveZombie();
 }


If you take the content of these functions and put it back in the Update function you'll find the result is quite similar to your original code but without the timer - since we're moving over time instead. I hope the use of the named functions makes it easier to understand what is going on.


Extra reading:
If I was asked to write this behaviour I would either use coroutines or a state machine. Since it's quite simple it's okay to be solved like this but if you want to learn more about control methods for behaviours such as these, I'd look into either of these instead. Additionally, the IsAtMovementTarget function is a little weak - the assumption that our movement will be less than 2 times our "close enough" value each frame is annoying. We can solve this by checking that we are also moving towards our target: we can find the dot product of our forward direction vector and the vector from our position to our target. I'll leave this up to you :)

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

144 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Animator Override Controller for NPC/ Overriding sprite animations 0 Answers

Jittery NPC movement? 2 Answers

NPC LookAt smoothing 2 Answers

How should I create a NPC System? 1 Answer

Distance to object and rotation lock 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges