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. Dismiss Notice

Question Weird problem with values on script

Discussion in 'Scripting' started by SamAdamsUK, Jun 27, 2023.

  1. SamAdamsUK

    SamAdamsUK

    Joined:
    Mar 21, 2023
    Posts:
    8
    Hi All,

    I could really do with some help on this as I've been trying to work out the issue for a while now. Apologies - this is a long post!

    I have a prefab of a rocket projectile, a script on the RocketLauncher (WeaponsSCR_RocketLauncher.cs), and on the prefab of the rocket projectile, another script (RocketProjectileScript.cs)

    Strangely, I have this working fine for the sniper rifle - I then butchered the scripts and created for the rocket launcher. The problem I have is: Every time I fire the weapon, the movement of the projectile is from a starting point where I previously fired the weapon! If I purely instantiate it without the mechanic of then moving the projectile/casting the ray in update/fixed update, then it does instantiate in the right position - always a little way in front of the main camera transform as intended. But as I say, this whole script seems to remember where I last fired the gun from and carry out the manouvre from there. I'm sure it's me not understanding variables, or the initialise order of a monobehaviour etc, but I could really do with a steer from you clever folks. Thanks!

    WeaponsSCR_RocketLauncher.cs

    Code (CSharp):
    1.  
    2. using System;
    3.  
    4. using System.Collections;
    5.  
    6. using System.Collections.Generic;
    7.  
    8. using Unity.VisualScripting;
    9.  
    10. using UnityEngine;
    11.  
    12. using UnityEngine.Assertions;
    13.  
    14. using UnityEngine.InputSystem;
    15.  
    16. using UnityEngine.Rendering.HighDefinition;
    17.  
    18. using UnityEngine.VFX;
    19.  
    20. using UnityEngine.Windows;
    21.  
    22. using static InputManager;
    23.  
    24. using static UnityEditor.PlayerSettings;
    25.  
    26. using static UnityEditor.ShaderGraph.Internal.KeywordDependentCollection;
    27.  
    28.  
    29. public class WeaponsSCR_RocketLauncher : MonoBehaviour
    30.  
    31. {
    32.  
    33.     public InputManager inputManager;
    34.  
    35.  
    36.     //public GameObject scopeCameraGameobject;
    37.  
    38.     //public Camera scopeCamera;
    39.  
    40.     //public Animator animator;
    41.  
    42.     //public Animation scopeAnimation;
    43.  
    44.  
    45.     //public float scopeZoomIncrementPercentage; //The percentage the Zoom increments on mouse wheel
    46.  
    47.     //public float scopeZoomIncrementDepthLimit; //The amount of times the player can zoom in, can be overwridden
    48.  
    49.     //public float scopeZoomIncrementCount; //The variable to count in and out on scope zoom
    50.  
    51.  
    52.  
    53.     public float shootSpeed;
    54.  
    55.     //public float gravityForce;
    56.  
    57.     public float rocketLifetime;
    58.  
    59.     public Vector3 rocketPosition;
    60.  
    61.  
    62.  
    63.     //public VisualEffect SniperMuzzleFlash;
    64.  
    65.     public GameObject rocketProjectilePrefab;
    66.  
    67.  
    68.     public GameObject mainCamera;
    69.  
    70.  
    71.  
    72.     private void Start()
    73.  
    74.     {
    75.  
    76.         inputManager = GetComponentInParent<InputManager>();
    77.  
    78.  
    79.      
    80.  
    81.         mainCamera = GameObject.FindWithTag("cam");
    82.  
    83.  
    84.     }
    85.  
    86.  
    87.     void OnEnable()
    88.  
    89.     {
    90.  
    91.         InputManager.OnFire += Fire;
    92.  
    93.  
    94.  
    95.     }
    96.  
    97.  
    98.     void OnDisable()
    99.  
    100.     {
    101.  
    102.         InputManager.OnFire -= Fire;
    103.  
    104.    
    105.  
    106.     }
    107.  
    108.  
    109.     public void Fire()
    110.  
    111.  
    112.     {
    113.  
    114.  
    115.          Vector3 rocketPosition = mainCamera.transform.TransformPoint(Vector3.forward * 2);
    116.  
    117.  
    118.  
    119.        GameObject rocketProjectile = Instantiate(rocketProjectilePrefab, rocketPosition , mainCamera.transform.rotation);
    120.  
    121.         RocketProjectileScript rocketProjectileScript = rocketProjectilePrefab.GetComponent<RocketProjectileScript>();
    122.  
    123.  
    124.         if (rocketProjectileScript)
    125.  
    126.          {
    127.  
    128.  
    129.  
    130.  
    131.           rocketProjectileScript.Initialize(rocketProjectile.transform, shootSpeed);
    132.  
    133.  
    134.         }
    135.  
    136.         Destroy(rocketProjectile, rocketLifetime);
    137.  
    138.  
    139.     }
    140.  
    141.  
    142.  
    143. }
    144.  
    RocketProjectileScript.cs

    Code (CSharp):
    1. RocketProjectileScript.cs
    2.  
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using System.Net;
    6. using UnityEngine;
    7.  
    8. public class RocketProjectileScript : MonoBehaviour
    9. {
    10.     public float speed;
    11.     private Vector3 startPosition;
    12.     private Vector3 startForward;
    13.  
    14.     private bool isInitialised = false;
    15.     private float startTime = -1;
    16.  
    17.     [SerializeField]
    18.     private GameObject rocketHolePrefab;
    19.  
    20.     public void Initialize(Transform startPoint, float speed) //Apparently cant use a constructor so this is doing the same thing
    21.  
    22.     {
    23.         Debug.Log("On Initialise, the start point is" + startPoint);
    24.         startPosition = startPoint.position;
    25.         startForward = startPoint.forward;
    26.         Debug.Log("On Initialise, startPosition (Startpoint.position) = " + startPosition);
    27.         Debug.Log("On Initialise, startForward (Startpoint.forward) = " + startForward);
    28.  
    29.         this.speed = speed;
    30.         isInitialised = true;
    31.     }
    32.  
    33.     public Vector3 FindPointOnPath(float time)
    34.     {
    35.         Debug.Log("Before performing FindPointOnPath, the startPosition is = " + startPosition);
    36.         Debug.Log("Before performing FindPointOnPath, the startForward is = " + startForward);
    37.         Vector3 point = startPosition + (startForward * speed * time);
    38.         Debug.Log("After performing FindPointOnPath, the returned 'point' is = " + point);
    39.         return point;
    40.  
    41.     }
    42.  
    43.     public bool CastRayBetweenPoints(Vector3 startPoint, Vector3 endPoint, out RaycastHit hit)
    44.     {
    45.         //Takes the two points on the Path, and returns a bool value and hit info if it hits something
    46.  
    47.         return Physics.Raycast(startPoint, endPoint - startPoint, out hit, (endPoint - startPoint).magnitude);
    48.     }
    49.  
    50.     //we need to get 2 of these points in each fixed update and cast the between them
    51.     //we repeat this process in every fixed update until we hit something or exceed the lifetime of the projectile.
    52.  
    53.      private void FixedUpdate() // this finds points along the path, controls the time since start, casts the ray between points, detects ray collision
    54.    {
    55.       Debug.Log("Fixed Update is running now");
    56.        Debug.Log("Fixed Update - isInitialised = " + isInitialised);
    57.        if (!isInitialised) return;
    58.        if (startTime < 0) startTime = Time.time; // startTime set as -1 initialy, so this sets the start time to current time ONLY in that case.
    59. //
    60.       float currentTime = Time.time - startTime; //get the difference in time from the start to now
    61.       float nextTime = currentTime + Time.fixedDeltaTime; //get the next time step
    62.  
    63.         //Calculate the 2 positions, pass them to the passraybetweenpoints method
    64.  
    65.        Vector3 currentPoint = FindPointOnPath(currentTime); //Find the current point on the simulated path
    66.        Vector3 nextPoint = FindPointOnPath(nextTime); // find the next point on the simulated path
    67.  
    68.      if (CastRayBetweenPoints(currentPoint, nextPoint, out RaycastHit hit)) // If it hits something, instantiate the hole decal and destroy the game object
    69.       {
    70.           GameObject obj = Instantiate(rocketHolePrefab, hit.point, Quaternion.LookRotation(hit.normal));
    71.           Destroy(gameObject);
    72.       }
    73.  
    74.     }
    75.  
    76.     private void Update() //this moves the bullet
    77.     {
    78.  
    79.  
    80.         if (!isInitialised || startTime < 0) return; // Dont start until FixedUpdate has done it's thing and set startTime from -1 to time.time
    81.         float currentTime = Time.time - startTime; //Another current time variable - but this is private.
    82.    
    83.        Vector3 currentPoint = FindPointOnPath(currentTime);
    84.         Debug.Log("After finding the currentPoint using FindPointOnPath, the position to move to is " + currentPoint);
    85.         transform.position = currentPoint;
    86.        //transform.position = transform.position + Vector3.forward * Time.deltaTime; //TEST - this moves it forward in world space (wrong). But ...So the problem is in Findpoint on path.....
    87.      }
    88.  
    89.  
    90. }
    91.  
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,559
    These are great places to start your investigation.

    I'm gonna guess that perhaps you are using the position of your prefab (what is on disk) as your spawn location, but I'll let you prove / disprove that theory. :)

    Time to start debugging! Here is how you can begin your exciting new debugging adventures:

    You must find a way to get the information you need in order to reason about what the problem is.

    Once you understand what the problem is, you may begin to reason about a solution to the problem.

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is
    - you're getting an error or warning and you haven't noticed it in the console window

    To help gain more insight into your problem, I recommend liberally sprinkling
    Debug.Log()
    statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the names of the GameObjects or Components involved?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as
    Debug.Log("Problem!",this);


    If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

    You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

    You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    Visit Google for how to see console output from builds. If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer for iOS: https://forum.unity.com/threads/how-to-capturing-device-logs-on-ios.529920/ or this answer for Android: https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/

    If you are working in VR, it might be useful to make your on onscreen log output, or integrate one from the asset store, so you can see what is happening as you operate your software.

    Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494

    "When in doubt, print it out!(tm)" - Kurt Dekker (and many others)

    Note: the
    print()
    function is an alias for Debug.Log() provided by the MonoBehaviour class.
     
    SamAdamsUK likes this.
  3. SamAdamsUK

    SamAdamsUK

    Joined:
    Mar 21, 2023
    Posts:
    8
    Wonderful - very useful, thank you!
     
    Kurt-Dekker likes this.
  4. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    521
    In RocketLauncher in your Fire method it looks like you are getting a script reference to the prefab rather than the one in the rocketProjectile

    GameObject rocketProjectile = Instantiate(rocketProjectilePrefab, rocketPosition , mainCamera.transform.rotation);
    RocketProjectileScript rocketProjectileScript = rocketProjectilePrefab.GetComponent<RocketProjectileScript>();
     
    SamAdamsUK and Kurt-Dekker like this.
  5. SamAdamsUK

    SamAdamsUK

    Joined:
    Mar 21, 2023
    Posts:
    8
    You're an absolute star - yes you're right, it works now! thankyou!!!!!!!!