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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Find Angle Between Two Objects Relative To Forward

Discussion in 'Scripting' started by FleshKnot, Jul 25, 2020.

  1. FleshKnot

    FleshKnot

    Joined:
    May 4, 2014
    Posts:
    67
    Hello. I currently have a few scripts, the main one I have inserted. Essentially they are old-school angle based sprite billboarding for multi-directional sprites. It works perfectly except for the fact that regardless of the orientation of the sprite object, the angle is still the same. I need the angle to be relative to the gameObject.transform.forward but so far, nothing I've done has worked.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5.  
    6. [RequireComponent(typeof(Animator))]
    7. public class AngleCalculator : MonoBehaviour
    8. {
    9.         public Animator objectAnimator;
    10.         private SpriteRenderer spriteRenderer;
    11.         private GameObject cameraParent;
    12.         private Vector3 localPosition;
    13.         private Vector3 cameraPosition;
    14.         private float localX;
    15.         private float localZ;
    16.         private float cameraX;
    17.         private float cameraZ;
    18.         public float angle;
    19.  
    20.         void Awake(){
    21.             cameraParent = GameObject.Find("Player");
    22.             objectAnimator = gameObject.GetComponent<Animator>();        
    23.             spriteRenderer = gameObject.GetComponent<SpriteRenderer>();  
    24.         }
    25.  
    26.  
    27.         void Update(){
    28.  
    29.         localPosition = gameObject.transform.position;
    30.                 localX = localPosition.x;
    31.                 localZ = localPosition.z;
    32.  
    33.             cameraPosition = cameraParent.transform.position;
    34.                 cameraX = cameraPosition.x;
    35.                 cameraZ = cameraPosition.z;
    36.  
    37.         angle = Mathf.Rad2Deg * Mathf.Atan2((cameraZ-localZ), (cameraX-localX));
    38.  
    39.         if (angle < 0){
    40.             angle = 360 + angle;
    41.         }
    42.  
    43.         Vector3 lookDirection = new Vector3(cameraParent.transform.forward.x, 0, cameraParent.transform.forward.z);
    44.             transform.LookAt(transform.position + lookDirection);
    45.  
    46.         if (angle >= 202 && angle <= 337.8){
    47.             spriteRenderer.flipX = true;
    48.         }
    49.             else {
    50.                 spriteRenderer.flipX = false;
    51.             }
    52.  
    53.         objectAnimator.SetFloat("ViewAngle", angle);
    54.  
    55.         }
    56.  
    57.     public void OnDrawGizmos(){
    58.  
    59.         if (!Application.isPlaying){
    60.             SceneView sceneView = GetActiveSceneView();
    61.             if (sceneView){
    62.                 Vector3 lookDirection = new Vector3(sceneView.camera.transform.forward.x, 0, sceneView.camera.transform.forward.z);
    63.                 transform.LookAt(transform.position + lookDirection);
    64.             }
    65.         }
    66.     }
    67.  
    68.     private SceneView GetActiveSceneView(){
    69.         if (EditorWindow.focusedWindow != null && EditorWindow.focusedWindow.GetType() == typeof(SceneView))
    70.             return (SceneView)EditorWindow.focusedWindow;
    71.  
    72.             return null;
    73.         }
    74. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,780
    I think you can do this by getting the
    transform.InverseTransformDirection()
    of each vector, then set the .Z to zero (effectively making them Vector2), then consider their angle. That would sorta be like an ortho view on the two vectors from the viewpoint of the transform.forward axis, like noon-day shadow casting.
     
  3. FleshKnot

    FleshKnot

    Joined:
    May 4, 2014
    Posts:
    67
    I can't set Z to 0, as Y is null in this case. I don't think I can calculate a slope with just X-intercept coordinates.
     
  4. FleshKnot

    FleshKnot

    Joined:
    May 4, 2014
    Posts:
    67
    I'm bumping this thread again. I've been at it for days. The closet I've gotten is by using InverseTransformPoint. This worked perfectly in the inspector view, but in game it didn't work at all. With the InverseTransformPoint, the relative angle stayed around 70.
     
  5. theratboy

    theratboy

    Joined:
    Sep 12, 2019
    Posts:
    1
    Any luck with this? I'm trying to do something similar.
     
  6. J_Troher

    J_Troher

    Joined:
    Dec 2, 2013
    Posts:
    42
    Same... Trying to make kind of an old school phone dialer. Have a circle, with points on it, and want to know the Angle between those points on the Circle, and a "reader" that is positioned above the outside of the circle, above it in the center. It would Light up as you pull the numbers around to the top.
    When that number is pulled to the top within a few degree's would cause that top light to turn on.. But When I have them lined up right now for some reason it starts at 54 degrees instead of 0... if I drag a number all the way around the dial, the angle goes from 54 to 125 then to -54 then to 0 (for a full spin...)
     
  7. gareth_untether

    gareth_untether

    Joined:
    Jan 5, 2018
    Posts:
    63