Search Unity

Feedback Looking tips on fixing targeting state behavior (Video and example project included)

Discussion in 'Scripting' started by Kamon145, Oct 13, 2022.

  1. Kamon145

    Kamon145

    Joined:
    Aug 27, 2022
    Posts:
    17
    Hello everyone! I am working on setting up a "targeting state" for my player right now using state machine system and Unitys new input system. Basically there is a large invisible trigger collider around the player, and when the targeting button is pressed, we switch from "free movement" to "targeting movement", as in movement becomes relative to the target, and the camera switches from being controlled by the player to being locked on to the player and the target. If there are multiple targets the one closest to the middle of the screen is chosen, and while locked on to a target the camera can be tilted slightly in all directions to switch targets. A button is assigned to switching targets which clears the current target, and checks all current available targets for the one closest to the center of the screen again.

    ..I'm pretty bad at describing things so I made a video demonstrating what I have working, as well as what problems I am having.. My main issue right now is trying to tilt the camera when looking at a target only works from the front... I am using a cinema chine targeting group camera to look at the player, the target, and an additional object that is placed at the targets transform position. The additional object is controllable with the right thumbstick but only moves correctly from the front. When releasing the thumbstick the object returns to the target position which recenters the view. The other main issue is this method doesn't work with mouse and keyboard controls. The other issues are minor things I'm sure I can work out along the way but these first 2 things are really keeping me from making much progress.
    As I'm using a state machine there's at least 3 different scripts all working together here, so rather than posting them all out here and making this longer than it already is I've uploaded a stripped down version of the projects to google drive, and the download link can be found here: https://www.dropbox.com/s/u9e96jvks3dfv3p/TargetingStateTestProject.zip?dl=0
    I realize I'm kinda asking a lot here but I'm really stuck here and wanted to see if anyone else had any ideas on how to do things better. I'm still so new to all this 3d stuff so figuring out quaternions and rotations in a 3d space is all very new and challenging to me. Thank you for reading and again, any help is greatly appreciated! && If you find anything useful in the project file, feel free to borrow!! Have a great day!!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    Welcome to debugging!

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

    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 or 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/

    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)

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

    This is my position on finite state machines (FSMs):

    https://forum.unity.com/threads/state-machine-help.1080983/#post-6970016

    I'm kind of more of a "get it working first" guy.

    Your mileage may vary.

    "I strongly suggest to make it as simple as possible. No classes, no interfaces, no needless OOP." - Zajoman on the Unity3D forums.
     
    Kamon145 likes this.
  3. Kamon145

    Kamon145

    Joined:
    Aug 27, 2022
    Posts:
    17
    Thank you for the reply! I do have quite a few debug logs thrown in when switching states and selecting targets, that has helped me catch instances of states triggering more than once and other simalar issues. I did not know about the other debug features though and will definitely be putting those to use in the future!
    My main issue I believe, is that I'm calculating the aim with a Vector2 and adding it to the targeters position, which is a Vector3. It makes sense that it moves the way it does cause its only recieving a 2D input, but I'm just not sure what the better approach to this would be here? Heres the bit of code I use to calculate the "aim" amount
    Code (CSharp):
    1.     private Vector2 CalculateAim()
    2.     {
    3.         Vector2 aim = new Vector2();
    4.  
    5.         float targetDistance = Vector3.Distance(stateMachine.transform.position, stateMachine.Targeter.CurrentTarget.transform.position);
    6.  
    7.         aim.x = stateMachine.InputReader.LookValue.x * targetDistance; //returns x value of joystick
    8.         aim.y = stateMachine.InputReader.LookValue.y * targetDistance; //returns y value of joystick
    9.  
    10.         Debug.Log("Aim Value of" + aim);
    11.  
    12.         return aim;
    13.     }
    The targetDistance part is to make it so the further away you are the more you can move the targeting cube, this function is called in update while in the targeting state and the aim value is added to the target value to get the position of the targeting cube:
    Code (CSharp):
    1. Vector2 aim = CalculateAim();
    2. stateMachine.FocusPoint.transform.position = new Vector3(targetPosition.x + aim.x, targetPosition.y + aim.y, targetPosition.z);
    Should I be using a Vector3 for the CalculateAim? or is there a way to add those to the Vector3 target position relative to where the player is standing? Or am I going about this all wrong?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    From looking at your video above, I must assume that Y is straight UP in the picture.

    X would be right / left, Z would be forward / backward

    If you cast or convert a Vector3 to a Vector2, you are losing the forward / backward: you're just dropping it and it becomes zero.

    That doesn't seem likely to be what you want given the planar orientation of your game.

    Vector2 really is only useful for stuff that is as flat as the video screen itself, never going forward / backwards. Otherwise use Vector3 always.
     
    Kamon145 likes this.
  5. Kamon145

    Kamon145

    Joined:
    Aug 27, 2022
    Posts:
    17
    GOT IT!! You got me thinking, the y movement worked the way it was supposed to, so I was able to just focus on the X and Z, I had to add aim.x to BOTH of them and than multiply by the characters transform.right to get it to work from all sides, this is the code I came up with in the end :
    Code (CSharp):
    1. stateMachine.FocusPoint.transform.position = new Vector3(targetPosition.x + aim.x * stateMachine.transform.right.x, targetPosition.y + aim.y, targetPosition.z + aim.x * stateMachine.transform.right.z);
    Thank you so much for taking the time and getting me looking in the right place! the other issues are mostly camera issues that I'm sure can be solved by tweaking the cinemachine settings, that was my main issue I wanted to address before going any further.
    Thank you again and have a great day!!
     
    Kurt-Dekker likes this.