Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 /
This post has been wikified, any user with enough reputation can edit it.
avatar image
0
Question by E_N · Nov 13, 2014 at 01:16 AM · lerpdetectionrangevector3.distance

How to get a game object to lerp as a triggered effect?

Trying to make an object move using lerp for movement and a bool for detecting when the player is close enough to trigger the effect. Preferably would like it to stay at the position once within the detection range but, a reverse lerp variant would also be welcome once leaving detection range. The anchor tagged object is another gameobject on the same initial position as the object i want to move. I have tagged the player and anchor.

 public float smooth;

 public float detectionRange = 2;
 private bool closeEnough;
 public float raiseAmount = 1;
 

 void Update () {
     
     Vector3 raise = new Vector3(0,raiseAmount,0);
     Vector3 player =  GameObject.FindGameObjectWithTag("Player").transform.position;
     Vector3 anchor = GameObject.FindGameObjectWithTag("Anchor").transform.position;
     
     closeEnough = false;
         if( Vector3.Distance( player, transform.position) <= detectionRange ){
          closeEnough = true;
         }
         else if(closeEnough == true){
             transform.position = Vector3.Lerp(transform.position, raise, smooth * Time.deltaTime);
         }
         if( Vector3.Distance( anchor, transform.position) >= detectionRange ){
             closeEnough = false;
         }
 
     }
 }
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

3 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Immanuel-Scholz · Nov 17, 2014 at 08:22 AM

Your main problem is, that Vector3.Lerp is lerping between two world coordinates, but your variable "raise" is a relative vector. This means you are not "lerping upwards the Y-axis" as you probably want to, but lerping towards the world position "0,y,0".

You can fix this, e.g. by using transform.position = transform.position + raise * smooth * Time.deltaTime instead of the lerp (which is basically a "lerp with relative vector") . Edit: It is not. See in comments. Use

 raise = transform.position + new Vector3(...)

` instead.

Some other problems with your code:

You are testing a 3D distance for the "detectionRange" from this object to the player. But then you move this object when the player is near. So unless you guarantee that the new position of this object is actually nearer to the player, it will be immediately moved out of detection range, jittering and stuttering every frame a bit. Easiest to fix this is to zero out the Y-axis before comparing the distance (to only calculate 2d distance). If you really need a full 3D distance, use some kind of "Schmidt-Trigger" which means you have a "detectionRange" when you enter the trigger and another "undetectionRange" slightly bigger that you test against for leaving the range.

Next, DO NOT USE ANY GameObject.Find* METHOD IN UPDATE() !!! It WILL kill your performance soon. Move them to Awake(). If you really need to find the player and anchor every frame (in case they might actually change a lot during the game - which I doubt. ;), then better have the player and anchor register/deregister themself in some of their scripts during their OnEnable/OnDisable.

Comment
Add comment · Show 13 · 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
avatar image E_N · Nov 17, 2014 at 08:20 PM 0
Share

Thank you for that detailed explanation, im still fresh at this so hear me out for this follow up question. How do you zero out the y axis? And will this allow the object to raise up a finite amount by raiseAmount.

avatar image Immanuel-Scholz · Nov 18, 2014 at 09:53 AM 0
Share

How do you zero out the y axis?

To measure "only the XZ distance" of an vector, the easiest way to grasp the idea is: copy them, write 0 to both y coordinates and then calculate the distance (it might be a couple of nanoseconds faster to do the distance math directly, but I leave that for you as a... home lesson! :P)

 Vector3 p1 = transform.position;
 Vector3 p2 = player;
 p1.y = 0;
 p2.y = 0;
 if (Vector3.Distance(p1, p2) <= detectionRange)
     ...

You can also move this code to an own function for easier later usage. I recommend an extension function to Vector3. Just create an class somewhere in your Asset folder:

 static class Vector3Extensions
 {
     public static float Distance2D(this Vector3 p1, Vector3 p2)
     {
         p1.y = 0;
         p2.y = 0;
         return Vector3.Distance(p1, p2);
     }
 }

And then you can simple use it by if (transform.position.Distance2D(player) <= ...

will this allow the object to raise up a finite amount by raiseAmount

It should not affect that part of the code.

avatar image E_N · Nov 18, 2014 at 11:48 PM 0
Share

Thank you again for explaining clearly, i will keep working at it.

avatar image E_N · Nov 19, 2014 at 12:49 PM 0
Share

This is my code now, which compiles without error. However the game object still does not move within the game. Any recommendations welcome.

using UnityEngine; using System.Collections;

public class Detection : $$anonymous$$onoBehaviour {

 public float smooth;
 public float detectionRange = 2;
 private bool closeEnough;
 public float raiseAmount = 1;
 public Vector3 player;
 public Vector3 anchor;
 
 void Awake ()
 {
     Vector3 player = GameObject.FindGameObjectWithTag("Player").transform.position;
     Vector3 anchor = GameObject.FindGameObjectWithTag("Anchor").transform.position;
 }
 
 void Update () 
 {
     Vector3 raise = new Vector3(0,raiseAmount,0);
     Vector3 p1 = player;
     Vector3 a1 = anchor;
     p1.y = 0;
     a1.y = 0;

             
     closeEnough = false;
         if( Vector3.Distance( p1, transform.position) <= detectionRange )
     {
          closeEnough = true;
     }
         else if(closeEnough == true)
     {
             transform.position = transform.position + raise * smooth * Time.deltaTime;
     }
         if( Vector3.Distance( a1, transform.position) >= detectionRange )
     {
             closeEnough = false;
     }
 
 }

}

avatar image Immanuel-Scholz · Nov 19, 2014 at 01:18 PM 0
Share

Two problems: First, you don't want to cache the player/anchor position at Awake. You want to cache the Player / Anchor

And second, you are storing them into local variables and ignore the class variable "player" and "anchor" (because you put an "Vector3" before the "player".

Try this:

 public float smooth;
 public float detectionRange = 2;
 private bool closeEnough;
 public float raiseAmount = 1;
 private Transform player;
 private Transform anchor;
 
 void Awake ()
 {
     player = GameObject.FindGameObjectWithTag("Player").transform;
     anchor = GameObject.FindGameObjectWithTag("Anchor").transform;
 }
 ...
 
     Vector3 p1 = player.position;
     Vector3 a1 = anchor.position;
 ...
Show more comments
avatar image
0

Answer by Achillies904 · Nov 24, 2014 at 04:38 PM

regardless of all the other solutions that everybody pointed out, i think there is a small error in the if statements

if i'm not mistaken, by using the "else if" statement your basically canceling the entrance to that if statement. meaning, if the distance is smaller than the detectionRange than you switch closeEnough to true, but than as long as the distance will remain smaller than the detectionRange than the code inside the second if statement will not be performed.

try changing this:

          if( Vector3.Distance( p1, transform.position) <= detectionRange )
      {
           closeEnough = true;
      }
          else if(closeEnough == true)
      {
              transform.position = transform.position + raise * smooth * Time.deltaTime;
      }

to this:

       if( Vector3.Distance( p1, transform.position) <= detectionRange )
      {
           closeEnough = true;
      }
       if(closeEnough == true)
      {
              transform.position = transform.position + raise * smooth * Time.deltaTime;
      }

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
avatar image
0

Answer by E_N · Nov 24, 2014 at 10:05 PM

With everyone's help it has accumulated to this. Anchor is now an individual GameObject so each object with this script can have their own anchor.

using UnityEngine; using System.Collections;

public class Detection : MonoBehaviour {

 public float smooth;
 public float detectionRange = 2;
 private bool closeEnough;
 public float raiseAmount = 1;
 private Transform player;
 private Transform anchor;
 public GameObject anchorOBJ;
 
 
 
 void Awake ()
 {
     player = GameObject.FindGameObjectWithTag("Player").transform;
     anchor = anchorOBJ.transform;
 }
 
 void Update () 
 {
     Vector3 raise = anchor.position + new Vector3(0,raiseAmount,0);
     Vector3 p1 = player.position;
     Vector3 a1 = anchor.position;
     p1.y = 0;
     a1.y = 0;

             
     closeEnough = Vector3.Distance(p1, a1) <= detectionRange;
          if (closeEnough)
              transform.position = Vector3.Lerp(transform.position, raise, smooth * Time.deltaTime);
         else
              transform.position = Vector3.Lerp(transform.position, anchor.position, smooth * Time.deltaTime);

 }

}

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

How to correctly do an enemy ranged attack script? 0 Answers

2D Enemy AI range problem 2 Answers

How to know if gameobject is in a circle in my canvas? 1 Answer

How to perform some code if you are close to an object 2 Answers

(Vector3.Lerp) Camera doesn't reach the specified Destination! 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