Search Unity

Question Help with Script

Discussion in 'Scripting' started by jfingerle2018, Nov 16, 2022.

  1. jfingerle2018

    jfingerle2018

    Joined:
    Aug 25, 2022
    Posts:
    10
    Hello everyone,

    I used the Third Person Game template provided by the wonderful development team, and copy-pasted the script for the default ThirdPersonController to a new controller for a different player entity whose animations work differently, IE I designed it to use the older 90s frame-by-frame style with seperate files for each animation instead of the skeletal style the template character uses.

    Although the rest of the script seems to be working fine because the compiler does not give me any errors or warnings/suggestions, it does tell me it expects a namespace or end-of-file even though I believe I typed in the correct number of parenthesis and/or semicolons. Does anybody know why this might be happening?

    The script is as follows, verbatim:

    Code (CSharp):
    1. using UnityEngine;
    2. #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
    3. using UnityEngine.InputSystem;
    4. #endif
    5. /* Note: animations are called via the controller for both the character and capsule using animator null checks
    6. */
    7. namespace StarterAssets
    8. {
    9.     [RequireComponent(typeof(CharacterController))]
    10. #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
    11.     [RequireComponent(typeof(PlayerInput))]
    12. #endif
    13.     public class BootsIdleController : MonoBehaviour
    14.     {
    15.     public GameObject BootsIdle;
    16.         [Header("Boots")]
    17.         [Tooltip("The character uses its own gravity value. The engine default is -9.81f")]
    18.         public float Gravity = -15.0f;
    19.         [Space(10)]
    20.         [Tooltip("Time required to pass before being able to jump again. Set to 0f to instantly jump again")]
    21.         public float JumpTimeout = 0.50f;
    22.         [Tooltip("Time required to pass before entering the fall state. Useful for walking down stairs")]
    23.         public float FallTimeout = 0.15f;
    24.         [Header("Player Grounded")]
    25.         [Tooltip("If the character is grounded or not. Not part of the CharacterController built in grounded check")]
    26.         public bool Grounded = true;
    27.         [Tooltip("Useful for rough ground")]
    28.         public float GroundedOffset = -0.14f;
    29.         [Tooltip("The radius of the grounded check. Should match the radius of the CharacterController")]
    30.         public float GroundedRadius = 0.28f;
    31.         [Tooltip("What layers the character uses as ground")]
    32.         public LayerMask GroundLayers;
    33.         [Header("Cinemachine")]
    34.         [Tooltip("The follow target set in the Cinemachine Virtual Camera that the camera will follow")]
    35.         public GameObject CinemachineCameraTarget;
    36.         [Tooltip("How far in degrees can you move the camera up")]
    37.         public float TopClamp = 70.0f;
    38.         [Tooltip("How far in degrees can you move the camera down")]
    39.         public float BottomClamp = -30.0f;
    40.         [Tooltip("Additional degress to override the camera. Useful for fine tuning camera position when locked")]
    41.         public float CameraAngleOverride = 0.0f;
    42.         [Tooltip("For locking the camera position on all axis")]
    43.         public bool LockCameraPosition = false;
    44.         // cinemachine
    45.         private float _cinemachineTargetYaw;
    46.         private float _cinemachineTargetPitch;
    47.         // player
    48.         private float _rotationVelocity;
    49.         // timeout deltatime
    50.         private float _jumpTimeoutDelta;
    51.         private float _fallTimeoutDelta;
    52. if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
    53.         private PlayerInput _playerInput;
    54. #endif
    55.         private CharacterController _controller;
    56.         private StarterAssetsInputs _input;
    57.         private GameObject _mainCamera;
    58.         private const float _threshold = 0.01f;
    59.         private bool IsCurrentDeviceMouse
    60.         {
    61.             get
    62.             {
    63. #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
    64.                 return _playerInput.currentControlScheme == "KeyboardMouse";
    65. #else
    66.                 return false;
    67. #endif
    68.             }
    69.         }
    70.         private void BootsAwake()
    71.             // get a reference to our main camera
    72.             if (_mainCamera == null)
    73.             {
    74.                 _mainCamera = GameObject.FindGameObjectWithTag("MainCamera");
    75.             }
    76.         }
    77.         private void BootsStart()
    78.         {
    79.             BootsIdle.SetActive(false);
    80.             _cinemachineTargetYaw = CinemachineCameraTarget.transform.rotation.eulerAngles.y;
    81.          
    82.             _controller = GetComponent<CharacterController>();
    83.             _input = GetComponent<StarterAssetsInputs>();
    84. #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
    85.             _playerInput = GetComponent<PlayerInput>();
    86. #else
    87.             Debug.LogError( "Starter Assets package is missing dependencies. Please use Tools/Starter Assets/Reinstall Dependencies to fix it");
    88. #endif
    89.         }
    90.         private void BootsUpdate()
    91.         {
    92.             BootsGroundedCheck();
    93.     if (Input.GetKey("left"))
    94. {
    95. BootsIdle.SetActive(false);
    96. }
    97.     if (Input.GetKey("right"))
    98. {
    99. BootsIdle.SetActive(false);
    100. }
    101.     if (Input.GetKey("down"))
    102. {
    103. BootsIdle.SetActive(false);
    104. }
    105.         if (Input.GetKey("up"))
    106. {
    107. BootsIdle.SetActive(false);
    108. };
    109.         }
    110.         private void BootsLateUpdate()
    111.         {
    112.             BootsCameraRotation();
    113.         }
    114.         private void BootsGroundedCheck()
    115.         {
    116.             // set sphere position, with offset
    117.             Vector3 spherePosition = new Vector3(transform.position.x, transform.position.y - GroundedOffset,
    118.                 transform.position.z);
    119.             Grounded = Physics.CheckSphere(spherePosition, GroundedRadius, GroundLayers,
    120.                 QueryTriggerInteraction.Ignore);
    121.         }
    122.         private void BootsCameraRotation()
    123.         {
    124.             // if there is an input and camera position is not fixed
    125.             if (_input.look.sqrMagnitude >= _threshold && !LockCameraPosition)
    126.             {
    127.                 //Don't multiply mouse input by Time.deltaTime;
    128.                 float deltaTimeMultiplier = IsCurrentDeviceMouse ? 1.0f : Time.deltaTime;
    129.                 _cinemachineTargetYaw += _input.look.x * deltaTimeMultiplier;
    130.                 _cinemachineTargetPitch += _input.look.y * deltaTimeMultiplier;
    131.             }
    132.             // clamp our rotations so our values are limited 360 degrees
    133.             _cinemachineTargetYaw = BootsClampAngle(_cinemachineTargetYaw, float.MinValue, float.MaxValue);
    134.             _cinemachineTargetPitch = BootsClampAngle(_cinemachineTargetPitch, BottomClamp, TopClamp);
    135.             // Cinemachine will follow this target
    136.             CinemachineCameraTarget.transform.rotation = Quaternion.Euler(_cinemachineTargetPitch + CameraAngleOverride,
    137.                 _cinemachineTargetYaw, 0.0f);
    138.         }
    139.      
    140.         private static float BootsClampAngle(float lfAngle, float lfMin, float lfMax)
    141.         {
    142.             if (lfAngle < -360f) lfAngle += 360f;
    143.             if (lfAngle > 360f) lfAngle -= 360f;
    144.             return Mathf.Clamp(lfAngle, lfMin, lfMax);
    145.         }
    146.         private void BootsOnDrawGizmosSelected()
    147.         {
    148.             Color transparentGreen = new Color(0.0f, 1.0f, 0.0f, 0.35f);
    149.             Color transparentRed = new Color(1.0f, 0.0f, 0.0f, 0.35f);
    150.             if (Grounded) Gizmos.color = transparentGreen;
    151.             else Gizmos.color = transparentRed;
    152.             // when selected, draw a gizmo in the position of, and matching radius of, the grounded collider
    153.             Gizmos.DrawSphere(
    154.                 new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z),
    155.                 GroundedRadius);
    156.             }
    157.     }
     
    Last edited: Nov 17, 2022
  2. jfingerle2018

    jfingerle2018

    Joined:
    Aug 25, 2022
    Posts:
    10
    Okay, I did figure it out, I just redid it from the ground and up and made a new class entirely at the very top of the script so that there was no wonkiness with clashing scripts with the old player class, but now I have a seperate problem I believe I raised last year, namely that I Googled the suggested codes for making the player disappear when you press the proper keys, but sadly nothing happens.

    Code (CSharp):
    1. using UnityEngine;
    2. #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
    3. using UnityEngine.InputSystem;
    4. #endif
    5. /* Note: animations are called via the controller for both the character and capsule using animator null checks
    6. */
    7. namespace StarterAssets
    8. {
    9.     [RequireComponent(typeof(CharacterController))]
    10. #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
    11.     [RequireComponent(typeof(PlayerInput))]
    12. #endif
    13.     public class BootsIdleThirdPersonController : MonoBehaviour
    14.     {
    15.         public GameObject BootsIdle;
    16.         [Header("Player")]
    17.         [Tooltip("Move speed of the character in m/s")]
    18.         public float MoveSpeed = 2.0f;
    19.         [Tooltip("Sprint speed of the character in m/s")]
    20.         public float SprintSpeed = 5.335f;
    21.         [Tooltip("How fast the character turns to face movement direction")]
    22.         [Range(0.0f, 0.3f)]
    23.         public float RotationSmoothTime = 0.12f;
    24.         [Tooltip("Acceleration and deceleration")]
    25.         public float SpeedChangeRate = 10.0f;
    26.         public AudioClip LandingAudioClip;
    27.         public AudioClip[] FootstepAudioClips;
    28.         [Range(0, 1)] public float FootstepAudioVolume = 0.5f;
    29.         [Space(10)]
    30.         [Tooltip("The height the player can jump")]
    31.         public float JumpHeight = 1.2f;
    32.         [Tooltip("The character uses its own gravity value. The engine default is -9.81f")]
    33.         public float Gravity = -15.0f;
    34.         [Space(10)]
    35.         [Tooltip("Time required to pass before being able to jump again. Set to 0f to instantly jump again")]
    36.         public float JumpTimeout = 0.50f;
    37.         [Tooltip("Time required to pass before entering the fall state. Useful for walking down stairs")]
    38.         public float FallTimeout = 0.15f;
    39.         [Header("Player Grounded")]
    40.         [Tooltip("If the character is grounded or not. Not part of the CharacterController built in grounded check")]
    41.         public bool Grounded = true;
    42.         [Tooltip("Useful for rough ground")]
    43.         public float GroundedOffset = -0.14f;
    44.         [Tooltip("The radius of the grounded check. Should match the radius of the CharacterController")]
    45.         public float GroundedRadius = 0.28f;
    46.         [Tooltip("What layers the character uses as ground")]
    47.         public LayerMask GroundLayers;
    48.         [Header("Cinemachine")]
    49.         [Tooltip("The follow target set in the Cinemachine Virtual Camera that the camera will follow")]
    50.         public GameObject CinemachineCameraTarget;
    51.         [Tooltip("How far in degrees can you move the camera up")]
    52.         public float TopClamp = 70.0f;
    53.         [Tooltip("How far in degrees can you move the camera down")]
    54.         public float BottomClamp = -30.0f;
    55.         [Tooltip("Additional degress to override the camera. Useful for fine tuning camera position when locked")]
    56.         public float CameraAngleOverride = 0.0f;
    57.         [Tooltip("For locking the camera position on all axis")]
    58.         public bool LockCameraPosition = false;
    59.         // cinemachine
    60.         private float _cinemachineTargetYaw;
    61.         private float _cinemachineTargetPitch;
    62.         // timeout deltatime
    63.         private float _jumpTimeoutDelta;
    64.         private float _fallTimeoutDelta;
    65. #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
    66.         private PlayerInput _playerInput;
    67. #endif
    68.         private Animator _animator;
    69.         private CharacterController _controller;
    70.         private StarterAssetsInputs _input;
    71.         private GameObject _mainCamera;
    72.         private const float _threshold = 0.01f;
    73.         private bool _hasAnimator;
    74.         private bool IsCurrentDeviceMouse
    75.         {
    76.             get
    77.             {
    78. #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
    79.                 return _playerInput.currentControlScheme == "KeyboardMouse";
    80. #else
    81.                 return false;
    82. #endif
    83.             }
    84.         }
    85.         private void Awake()
    86.         {
    87.             // get a reference to our main camera
    88.             if (_mainCamera == null)
    89.             {
    90.                 _mainCamera = GameObject.FindGameObjectWithTag("MainCamera");
    91.             }
    92.         }
    93.         private void Start()
    94.         {
    95.             _cinemachineTargetYaw = CinemachineCameraTarget.transform.rotation.eulerAngles.y;
    96.             _controller = GetComponent<CharacterController>();
    97.             _input = GetComponent<StarterAssetsInputs>();
    98. #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
    99.             _playerInput = GetComponent<PlayerInput>();
    100. #else
    101.             Debug.LogError( "Starter Assets package is missing dependencies. Please use Tools/Starter Assets/Reinstall Dependencies to fix it");
    102. #endif
    103.             // reset our timeouts on start
    104.         }
    105.         private void Update()
    106.         {
    107.             GroundedCheck();
    108. if ( Input.GetKeyDown(KeyCode.LeftArrow) == true )
    109. {
    110. BootsIdle.GetComponent<Renderer>().enabled = false;
    111. }
    112. if ( Input.GetKeyDown(KeyCode.RightArrow) == true )
    113. BootsIdle.GetComponent<Renderer>().enabled = false;
    114. if ( Input.GetKeyDown(KeyCode.UpArrow) == true )
    115. BootsIdle.GetComponent<Renderer>().enabled = false;
    116. if ( Input.GetKeyDown(KeyCode.DownArrow) == true )
    117. BootsIdle.GetComponent<Renderer>().enabled = false;
    118.         }
    119.         private void LateUpdate()
    120.         {
    121.             CameraRotation();
    122.         }
    123.         private void GroundedCheck()
    124.         {
    125.             // set sphere position, with offset
    126.             Vector3 spherePosition = new Vector3(transform.position.x, transform.position.y - GroundedOffset,
    127.                 transform.position.z);
    128.             Grounded = Physics.CheckSphere(spherePosition, GroundedRadius, GroundLayers,
    129.                 QueryTriggerInteraction.Ignore);
    130.         }
    131.         private void CameraRotation()
    132.         {
    133.             // if there is an input and camera position is not fixed
    134.             if (_input.look.sqrMagnitude >= _threshold && !LockCameraPosition)
    135.             {
    136.                 //Don't multiply mouse input by Time.deltaTime;
    137.                 float deltaTimeMultiplier = IsCurrentDeviceMouse ? 1.0f : Time.deltaTime;
    138.                 _cinemachineTargetYaw += _input.look.x * deltaTimeMultiplier;
    139.                 _cinemachineTargetPitch += _input.look.y * deltaTimeMultiplier;
    140.             }
    141.             // clamp our rotations so our values are limited 360 degrees
    142.             _cinemachineTargetYaw = ClampAngle(_cinemachineTargetYaw, float.MinValue, float.MaxValue);
    143.             _cinemachineTargetPitch = ClampAngle(_cinemachineTargetPitch, BottomClamp, TopClamp);
    144.             // Cinemachine will follow this target
    145.             CinemachineCameraTarget.transform.rotation = Quaternion.Euler(_cinemachineTargetPitch + CameraAngleOverride,
    146.                 _cinemachineTargetYaw, 0.0f);
    147.         }
    148.         private static float ClampAngle(float lfAngle, float lfMin, float lfMax)
    149.         {
    150.             if (lfAngle < -360f) lfAngle += 360f;
    151.             if (lfAngle > 360f) lfAngle -= 360f;
    152.             return Mathf.Clamp(lfAngle, lfMin, lfMax);
    153.         }
    154.         private void OnDrawGizmosSelected()
    155.         {
    156.             Color transparentGreen = new Color(0.0f, 1.0f, 0.0f, 0.35f);
    157.             Color transparentRed = new Color(1.0f, 0.0f, 0.0f, 0.35f);
    158.             if (Grounded) Gizmos.color = transparentGreen;
    159.             else Gizmos.color = transparentRed;
    160.             // when selected, draw a gizmo in the position of, and matching radius of, the grounded collider
    161.             Gizmos.DrawSphere(
    162.                 new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z),
    163.                 GroundedRadius);
    164.         }
    165.     }
    166. }
    What I would like anyone who is helping correct the problem focus on is the snippet regarding the "If Key is Pressed" section, with the scripts making the renderer false/disappear, which is not happening currently even though the script compiles correctly.
     
    Last edited: Nov 17, 2022
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,491
    Please don't post walls of plain text for code, use code-tags. You can also edit your posts.

    Note, this thread is nothing to do with the Editor so this is also the wrong forum, it's a Scripting post so I'll move it there.

    Here's the page that lists all the available forums: https://forum.unity.com/
     
  4. jfingerle2018

    jfingerle2018

    Joined:
    Aug 25, 2022
    Posts:
    10
    Thank you for the help/moderation. I am really sorry I made those mistakes and will make sure to follow your directions in the future regarding pasting code, as well as where I post the question. I thought it was about the editor and general help cause I used the editor for making my game overall as well as scripting, but if it's regarding scripting help explicitly it should go in scripting period?
     
  5. AnimalMan

    AnimalMan

    Joined:
    Apr 1, 2018
    Posts:
    1,164
    That code is really hard to read buddy.
     
  6. jfingerle2018

    jfingerle2018

    Joined:
    Aug 25, 2022
    Posts:
    10
    Is it because of the lack of code tags, or because of something else? I will change it to code tags too if that is the problem.
     
  7. jfingerle2018

    jfingerle2018

    Joined:
    Aug 25, 2022
    Posts:
    10
    And this particular snippet I can isolate, to make it more obvious what is not working properly:

    Code (CSharp):
    1. if ( Input.GetKeyDown(KeyCode.LeftArrow) == true )
    2. {
    3. BootsIdle.GetComponent<Renderer>().enabled = false;
    4. }
    5. if ( Input.GetKeyDown(KeyCode.RightArrow) == true )
    6. BootsIdle.GetComponent<Renderer>().enabled = false;
    7. if ( Input.GetKeyDown(KeyCode.UpArrow) == true )
    8. BootsIdle.GetComponent<Renderer>().enabled = false;
    9. if ( Input.GetKeyDown(KeyCode.DownArrow) == true )
    10. BootsIdle.GetComponent<Renderer>().enabled = false;
    Should I use a different method besides "object.GetComponent<Renderer>().enabled = false", like "object.setactive(false)"? I tried that because I got that result from Googling it as well, but unfortunately it still didn't work.
     
  8. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    Hello. I'm not sure what the entire thing is doing but it is (generally speaking) not very efficient at doing it. That is from the aspect of time of course (which I'm not focused on) and from readability which is in my mind equally important.

    For instance: BootsIdle.GetComponent<Renderer>() is repeated several times. That reference isn't changing is it? So get it once outside of the method and hold on to the reference.

    It is set to false based upon the state of 4 conditions. How about adding method that returns the status of the 4 Inputs and then you just assign the result. Something like:

    Code (CSharp):
    1. bootsIdleRenderer.enabled = IsKeyDown();
    In BootsOnDrawGizmosSelected you continually assign values to transparentGreen and transparentRed but again those never change so assign them once outside of that method.

    Code (CSharp):
    1. Gizmos.color = Grounded ? transparentGreen : transparentRed;
    And finally "whitespace is your friend". It is also free, add some :)
     
  9. jfingerle2018

    jfingerle2018

    Joined:
    Aug 25, 2022
    Posts:
    10
    Thank you for the help! I do not know if I should change BootsGizmo though, because I was just copy pasting it verbatim from the character template like I explained in my first post, so it might alter other parts of the code that rely on it. The first suggestion you stated though I can and will definitely do.
     
  10. jfingerle2018

    jfingerle2018

    Joined:
    Aug 25, 2022
    Posts:
    10
    I think there might be bugs too now, because I am told the local function "LateUpdate" is declared but never used, even though I know it wasn't a problem for the default template I pasted it from, and I didn't change that particular code at all. What gives?
     
  11. jfingerle2018

    jfingerle2018

    Joined:
    Aug 25, 2022
    Posts:
    10
    Do you think it might be cause I copy pasted most of the script, like I assumed the "Update" and "LateUpdate" functions would carry over seamlessly into my new class, even though it is actually reserved for the PlayerClass specifically? I could guess that
     
  12. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    I didn't notice your reply. It isn't "reserved" this is all just code you tell it what you want it doesn't tell you :) So long as your new class inherits MonoBehaviour you get the standard methods.

    Experimentation is one of the best ways to get a feel for how coding works and will build confidence. I would suggest not "guessing" that is one of the worst systems and likely to lead to "well I must be correct because now it works". You could have just gotten lucky. Know why the code works and why changing (improving) something would work even better.

    That's my 2 cents.
     
  13. jfingerle2018

    jfingerle2018

    Joined:
    Aug 25, 2022
    Posts:
    10
    Okay, then it is actually worse that way, because I used the same exact code snippet for the original Player character and my new character, yet it gives me an error for new character. I don't believe it is good practice when developing an app to make one's code inconsistent and logically unpredictable like that.
     
  14. jfingerle2018

    jfingerle2018

    Joined:
    Aug 25, 2022
    Posts:
    10
    Cause what I am refererring to is when you start a new project from the ground up, you are given a "third person game template" with a character who has a working script already. In that exact/particular script, it gives you scripts for "Update" and "LateUpdate", even though it is never called earlier in the code it picks up on that it should do the code every single frame/update.

    When I copy paste the script and make the revisions in other places of the code, not that piece at all, it gives me an error message saying "Update" was never called even though that was exactly as true for the original character, and it never complained/gave me an error.
     
  15. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    I have to guess based upon what you are writing that you don't exactly understand how the MonoBehavior works or why it is there. That isn't a problem when starting out but you need to get to the point of knowing it isn't just a magic word you need to type. Update isn't a script it is a method and it didn't "not get called" it always gets called by Unity automatically as part of the lifecycle of the class.

    You can post the class (make sure you embed it as
    Code (CSharp):
    1. code
    . The issue can be a lot of things, C# is case-sensitive and you might have decided that case shouldn't matter. Sometimes people spell things wrong and sometimes they misinterpret error messages. They can happen in the editor, the compiler or at runtime all for different reasons.

    I suggest that you try again and take it one step at-a-time. We've all been there.