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 /
avatar image
2
Question by leenalee92 · Dec 03, 2014 at 04:32 PM · javascripttransform.positionvector3.lerp

Vector3.Lerp doesn't work

Hi there! this is my puzzle gamealt text

And this is my script (I cut it short):

 var emptySlot: Transform;
 var xtemp;
 var ytemp;
 var Tile1Pos : GameObject;
 var Tile2Pos : GameObject;
 var Tile3Pos : GameObject;
 var speed : float= 0.01f;
 
 function Update()
 {
     Tile1Pos= GameObject.Find("Tile_1");
     
     Tile2Pos= GameObject.Find("Tile_2");
 
     Tile3Pos= GameObject.Find("Tile_3");
 }
 
 function OnMouseUp()
 {
     
     if (Vector3.Distance(transform.position,emptySlot.position)< 3.2)
     {
         xtemp= transform.position.x;
         ytemp= transform.position.y;
         transform.position.x= emptySlot.position.x;
         transform.position.y= emptySlot.position.y;
         emptySlot.position.x= xtemp;
         emptySlot.position.y= ytemp;
                 
             var movement = speed * Time.deltaTime;
         Tile1Pos.transform.position = Vector3.Lerp( Tile1Pos.transform.position, emptySlot.position, movement);
 
         Tile2Pos.transform.position = Vector3.Lerp( Tile2Pos.transform.position, emptySlot.position, movement);
 
         Tile3Pos.transform.position = Vector3.Lerp( Tile3Pos.transform.position, emptySlot.position, movement);
      }

If i write like this, i didn't get any error message but my tile won't change the position with my empty slot slowly. I don't know why so i tried like this:

 Tile3Pos.transform.position = Vector3.Lerp( transform.position, emptySlot.position, movement);

After i click my tile, all my tile just fly away @@!

If i write my Vector3.Lerp to function Update column, my tile just keep changing their position automatically. Can someone tell me what's the problem here?

36417-puzzle_game.jpg (268.3 kB)
Comment
Add comment · Show 8
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 NoseKills · Dec 03, 2014 at 08:49 PM 0
Share

I was trying to convert my previous answer to a comment but Answers bugged out and it disappeared completely... which is O$$anonymous$$ since it wasn't a good answer anyways =)

Is the mechanic you are looking for perhaps for a game like this ?

EDIT: oh now it's there again...

avatar image Eck · Dec 03, 2014 at 09:42 PM 0
Share

Your lerp is in On$$anonymous$$ouseUp() so only gets called once per $$anonymous$$ouseUp event. Sure, you wired in a Time.deltaTime piece, but that doesn't really make sense in the context of this function.

To Lerp (linear interpolate) an object moving from 1 location to the next, you need to wire this bit into Update() or start a coroutine that moves the position of your game object.

avatar image leenalee92 · Dec 04, 2014 at 03:02 AM 0
Share

@Nose$$anonymous$$ill yea, i'm creating a game like that, i just cut it short so the question won't too long

@Eck i try to put the lerp in update already, but my tile just fly away, why?

avatar image leenalee92 · Dec 04, 2014 at 08:44 AM 0
Share

in this case..can i just apply Time.deltaTime ins$$anonymous$$d of Vector3.Lerp to my tile, give them speed so that they can swap their position smoothly,not just teleport to the position?

if yes, what can i do with my script?

avatar image NoseKills · Dec 04, 2014 at 09:06 AM 0
Share

Now that i know what you want to achieve, I'll try to give you an example when i get home in about 7 hours unless someone beats me to it. Hang in there !

Show more comments

3 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by jenci1990 · Dec 04, 2014 at 09:43 AM

 var emptySlot: Transform;
 var xtemp;
 var ytemp;
 var Tile1Pos : GameObject;
 var Tile2Pos : GameObject;
 var Tile3Pos : GameObject;
 private var speed : float= 1f;
 
 function Start() {
     Tile1Pos= GameObject.Find("Tile_1");
     Tile2Pos= GameObject.Find("Tile_2");
     Tile3Pos= GameObject.Find("Tile_3");
 }
 function OnMouseUp() {
     if (Vector3.Distance(transform.position,emptySlot.position)< 3.2f) {
         Change();
     }
 }
 
 function Change() {
     var timer : float = 0f;
     var myPos : Vector3 = transform.position;
     var emptyPos : Vector3 = emptySlot.position;
     while (timer <= 1f) {
         timer += Time.deltaTime * speed;
         transform.position = Vector3.Lerp(transform.position, emptyPos, timer);
         emptySlot.position = Vector3.Lerp(emptySlot.position, myPos, timer);
         yield WaitForEndOfFrame();
     }
     transform.position = emptyPos;
     emptySlot.position = myPos;
     return;
 }
Comment
Add comment · Show 6 · 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 leenalee92 · Dec 04, 2014 at 10:13 AM 0
Share

hi @jenci1990, this code is work but when i click my tile to swap position, all my tile just fly away..

avatar image jenci1990 · Dec 04, 2014 at 11:17 AM 0
Share

Do tiles contanis this script?? if no attach this scrip to all 3 tiles, but only to tiles!

avatar image leenalee92 · Dec 04, 2014 at 11:19 AM 0
Share

yes, all my tiles attach with this script(included emptySlot tile), for my emptySlot tile, do i need to attach this script too?

avatar image leenalee92 · Dec 04, 2014 at 11:25 AM 0
Share

it seems like rotated too

avatar image jenci1990 · Dec 04, 2014 at 11:42 AM 0
Share

alt text

This works for me with my script.

tut.jpg (46.9 kB)
tut2.jpg (40.5 kB)
Show more comments
avatar image
0

Answer by sed · Dec 04, 2014 at 09:55 AM

Well, the problem here is that you shouldn't be using just the Time.deltaTime in the lerp.

http://docs.unity3d.com/ScriptReference/Vector3.Lerp.html

Because here is how Lerp works: "Interpolates between a and b by t. t is clamped between 0 and 1."

So for the lerp to actually "get there" you need to maintain a counter, here is a simple Coroutine:

 function lerpBetweenPositions(who : transform, a : Vector3 , b: Vector3, duration : float){
      var counter : float = 0.0f;
      while(counter < 1.0f){
          transform.position = Vector3.Lerp(a, b, counter);
 
          counter += Time.deltaTime / duration;
          yield;
      }
      transform.position = b; // its important to clamp the lerp to final position
  }
 

Alternatively using SmoothDamp might be more intuitive for you: http://docs.unity3d.com/ScriptReference/Vector3.SmoothDamp.html

Update: It's common mistake to use any of the Unity's Lerp with a constant or near constant value every frame. If your doing Lerp(a, b, deltaTime * scaler) every frame then the output might be visually similar to what you want to achieve but in fact it's not. Look at this pseudocode of how lerp works: Lerp(a,b,t) = (1-t)*a + t*b

ie. at t = 0 -> Lerp(a,b,0) = a; at t = 1 -> Lerp(a,b,1) = b;

at any point between 0 and 1 it's simple linear interpolation of the result.

Since Time.deltaTime is very similar every frame, when you use a scaler value (like a constant speed, 0.3f or whatever) a

a = Lerp(a,b, Time.deltaTime * scaler) the animation will never reach b. In fact just don't get the control over the animation you could achieve using SmoothDampen or whatever.

In my approach in the code above to get smoothing and full control over the animation you can use

 function lerpBetweenPositions(who : transform, a : Vector3 , b: Vector3, duration : float){
      var counter : float = 0.0f;
      while(counter < 1.0f){
          transform.position = Vector3.Lerp(a, b, Mathf.SmoothStep(0.0f, 1.0f, counter));
 
          counter += Time.deltaTime / duration;
          yield;
      }
      transform.position = b; // its important to clamp the lerp to final position
  }



Similar question: http://answers.unity3d.com/questions/620401/mathflerp-never-gets-there.html

Comment
Add comment · Show 8 · 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 leenalee92 · Dec 04, 2014 at 10:29 AM 0
Share

Please give me some time, i'm trying to figure this out, i just start coding around 2 month, thanks for your suggestion

avatar image leenalee92 · Dec 04, 2014 at 10:41 AM 0
Share

Hi @sed, i tried like this

 function On$$anonymous$$ouseUp()
     {        
         if (Vector3.Distance(transform.position, emptySlot.position )< 3.5f)
         {
             lerpBetweenPosition();            
         }
     }
     
     function lerpBetweenPosition ()
     {
         var emptySlot: Transform;
         var TilePos: Vector3 = transform.position;
         var emptyPos: Vector3 = emptySlot.position;
         var duration:float;
         var counter : float = 0.0f;
         
         while (counter< 1.0f)
            {
              transform.position = Vector3.Lerp (TilePos, emptyPos, counter);
         
              counter = Time.deltaTime/duration;
              yield;
            }
         TilePos = transform.position;
         transform.position = emptyPos;
     }    
 

i got this error message:

NullReferenceException: Object reference not set to an instance of an object

$$anonymous$$ovement_ClickLimit_L1+$lerpBetweenPosition$41+$.$$anonymous$$oveNext () (at Assets/Scripts/Level_Script/$$anonymous$$ovement_ClickLimit_L1.js:72)

UnityEngine.$$anonymous$$onoBehaviour:StartCoroutine_Auto(IEnumerator)

$$anonymous$$ovement_ClickLimit_L1:On$$anonymous$$ouseUp() (at Assets/Scripts/Level_Script/$$anonymous$$ovement_ClickLimit_L1.js:41)

UnityEngine.Send$$anonymous$$ouseEvents:DoSend$$anonymous$$ouseEvents()

avatar image Lunatix · Dec 04, 2014 at 10:52 AM 0
Share

This is a bit to complex and not a smart way to solve the problem. The documentation of the Vector3.Lerp method shows a very good way to use the method: http://docs.unity3d.com/ScriptReference/Vector3.Lerp.html

One should pass Time.deltaTime and scale it up or down to increase or decrease speed of the interpolation: transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * lerpScaler);

avatar image leenalee92 · Dec 04, 2014 at 10:57 AM 0
Share

i tried Vector3.Lerp, but i don't know why after i clicked my tile, they swap but they also fly away from the puzzle box

avatar image sed · Dec 04, 2014 at 11:59 AM 0
Share

@Lunatix you might want to read the documentation again. It's very common mistake you've made there. I'll update the answer to make it more clear.

Show more comments
avatar image
0

Answer by Lunatix · Dec 04, 2014 at 12:45 PM

I made a simple example project which can be downloaded here: https://www.dropbox.com/s/zt02y7bcg5nae1q/TileMapController.7z?dl=0

Let me explain the workflow:

First, I created a tile map controller which is capable of controlling slots and tiles. The click events are achived by using box colliders marked as "Trigger".

The tile map controller identifies all attached slots by searching for a component called "SlotController". A slot controller can be marked as "Leave Empty on Start" so it will not be filled.

All slots not marked as empty will be filled automatically by instantiating a new tile, defined by a prefab and a component called "TileController" will be added to the instantiated object.

SlotControllers and TileControllers will notify the TileMapController about click events - the tile map controller then decides if a tile can be moved to the clicked position.

While the tile is lerping to the new position it will prevent mouse clicks to prevent movements in "mid air".

I did not implement drag and drop for the sake of simplicity - just click a tile and an empty slot to start the movement.

If your want to have more slots, simply copy and paste one of the game objects called "Slot".

Comment
Add comment · Show 4 · 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 leenalee92 · Dec 04, 2014 at 01:46 PM 0
Share

hi @Lunatix thanks for your effort, but i can't open the file, because my unity version is 3.5.0 :(

avatar image Lunatix · Dec 04, 2014 at 01:51 PM 0
Share

Uhm.. try to update to the latest version, maybe ;)? There will be no disadvantages for you :) But I think you can use the scripts with unity 3.5, too.

avatar image leenalee92 · Dec 04, 2014 at 01:59 PM 0
Share

yeap, i can open the script with my unity too, but i don't know c#, i will try my best to convert it to javascript :) this script can apply on 3D game object right?

avatar image Lunatix · Dec 04, 2014 at 02:42 PM 0
Share

Yes. Do the following:

[GameObject] (Attach Tile$$anonymous$$apController.cs) - [Sprite with BoxCollider] (Attach SlotController.cs) - [Sprite with BoxCollider] (Attach SlotController.cs) - [Sprite with BoxCollider] (Attach SlotController.cs) - [Sprite with BoxCollider] (Attach SlotController.cs, LeaveEmptyAtStartup: false)

And assign a Sprite Prefab to the Tile$$anonymous$$apController.

Image #1 Image #2 Image #3

[1]: https://www.dropbox.com/s/fx1rjdiq23w8wed/editor-3.png?dl=0

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

8 People are following this question.

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

Related Questions

Can someone help me fix my Javascript for Flickering Light? 6 Answers

why one works, the other does not 2 Answers

whats wrong with my save/load script? (transform.position) 1 Answer

How to move a object forward relative to it smoothly without update function? 1 Answer

Swap texture2D on enemy sprite once reached a certain point 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