Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Object moving at lightspeed

Discussion in 'Scripting' started by Henri_fodinha, May 6, 2022.

  1. Henri_fodinha

    Henri_fodinha

    Joined:
    Apr 15, 2022
    Posts:
    2
    I'm creating an enemy that is supposed to continuosly move up and down using Transform p1 and p2, which is working perfectly. I also want it to move foward quickly and back to it's original position every few seconds, which is void Bite()'s function, the problem is that when it invokes the method, it happens too quickly and the only way to know that it's happening is by observing the objects Transform, does anyone have any idea on how to fix this?




    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5.  
    6. public class Shark : MonoBehaviour
    7. {
    8.     public Transform p1;
    9.     public Transform p2;
    10.     public float speed;
    11.     public float maxTime;
    12.     float time;
    13.     public Transform pMove1;
    14.     public Transform pMove2;
    15.     public float val;
    16.     public int vida;
    17.     void OnCollisionEnter(Collision collision){
    18.              if(collision.gameObject.CompareTag("Bullet")){
    19.                 vida = vida - 1;
    20.             }
    21. }
    22.     float t;
    23.     void FixedUpdate()
    24.     {
    25.         t = Mathf.PingPong(Time.time * speed, 1.0f);
    26.         time += Time.fixedDeltaTime;
    27.         if(time > maxTime)
    28.         {
    29.             Invoke("Bite", 0.0f);
    30.             time = 0.0f;
    31.         }
    32.         transform.position = Vector3.Lerp(p1.position, p2.position, t);
    33.          if(vida <= 0){
    34.             Destroy(gameObject);
    35.               GameManager.Instance.worth = val;
    36.                 GameManager.Instance.Addpontos();
    37.             SceneManager.LoadScene("Levelselect2");
    38.         }
    39.  
    40.     }
    41.    void Bite()
    42.     {
    43.         transform.position = Vector3.Lerp(pMove1.position, pMove2.position, t);
    44.     }
    45.  
    46. }
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,735
    This code is a big headscratcher:
    Invoke("Bite", 0.0f);


    Why invoke something with 0 second timer. In that case you would just call the function directly.
    And that's basically what's happening here. you're just calling Bite() one time. If you want something to move smoothly from one position to another, obviously you will need to have code that is running every frame for the duration of that movement, moving the object little by little.

    A common misconception for beginners is that Lerp is somehow some magic function that does something like that. It is not. Lerp is simply a mathematical formula, it doesn't do anything over time or anything like that.
     
  3. Henri_fodinha

    Henri_fodinha

    Joined:
    Apr 15, 2022
    Posts:
    2
    Hey, thanks for answering! I've been trying a few things but nothing has worked so far. Changing the float value for invoke, calling the method without invoke, changing the method to IEnumerator, using StartCoroutine and using transform.translate inside Bite() all make the object move up and down without ever going to pMove1. Maybe i'll create an animation that plays whenever the cooldown ends, will try when i have some free time
     
  4. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,735
    You've tried everything except actually applying the motion over the course of multiple frames. That's the key. Note that currently you have code that unconditionally sets the position of your object in FixedUpdate. So that is going to trample all over anything you do in any coroutine etc. anyway. You need to think about the object's position each frame and how your code is running and how it all interacts together.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,962
    Right away I can see some warning flags here.

    You have an OnCollisionEnter method, which implies you care about physics collision and have a rigidbody.

    And yet there are at least two lines where you are directly manipulating the transform position, which completely bypasses physics.

    With Physics (or Physics2D), never manipulate the Transform directly. If you manipulate the Transform directly, you are bypassing the physics system and you can reasonably expect glitching and missed collisions and other physics mayhem.

    Always use the .MovePosition() and .MoveRotation() methods on the Rigidbody (or Rigidbody2D) instance in order to move or rotate things. Doing this keeps the physics system informed about what is going on.

    https://forum.unity.com/threads/col...-unity-physic-rigidbody.1216875/#post-7763061

    https://forum.unity.com/threads/oncollisionenter2d-not-being-called.1266563/#post-8044121

    With a wheel collider, use the motor or brake torque to effect motion.
     
    PraetorBlue likes this.