Unity 3D 化 Anchor Presets 判断一个 对象 对应另一个对象的位置,左,右,上,下

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/KiTok/article/details/80338743

Hello ,I am Edwin


首先谢谢大家的支持,其次如果你碰到什么其他问题的话,欢迎来 我自己的一个 讨论群559666429来,大家一起找答案,共同进步

由于逻辑比较简单,所以直接代码吧。功能主要是 :

注意: 使用这个功能的时候 摄像机的 旋转 必须 都为 0。负责要么,你要稍微调节代码,要不就没有办法使用

1. 获得 A相对与B所在的位置。直接 得出,是在B的 左边,右边,还是上边,亦或者 下边。 针对读者是 Unity 基础者。顺路造福一下人类,高手绕路。

这里写图片描述

2. 制作像 UGUI Anchor Presets 一样效果的 ,让子类对象去 父类对象的 左边,右边,左上角,右上角,左下角…..

这里写图片描述


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum Azimuth
{
    Zero,
    UpperLeft,
    UpperRight,
    LowerRight,
    LowerLeft,

    Left,
    Right,
    Up,
    Down,
}

public class JudgmentDirection : MonoBehaviour {

    public GameObject other;

    float dot ;
    float dot_angle;
    Vector3 cross;

    bool isZheng = false;
    bool isShun = false;

    public Azimuth m_Azimuth;

    Azimuth fangwei ;

    private void FixedUpdate()
    {
        if(other)
        {
            fangwei =  GetAzimuth(other.transform);
        }
    }

    Azimuth GetAzimuth(Transform other)
    {
        Vector3 dic = other.transform.position - transform.position;

        dot = Vector3.Dot(dic.normalized, transform.up);
        dot_angle = Mathf.Acos(dot) * Mathf.Rad2Deg;

        isZheng = (Mathf.Sign(dot) == -1) ? false : true;

        cross = Vector3.Cross(dic.normalized, transform.up);
        isShun = (cross.z >= 0) ? true : false;

        float maxValue = Mathf.Cos(45.0f * Mathf.Deg2Rad);
        Debug.Log(maxValue);
        if (Mathf.Abs(dot) > maxValue)
        {
            if (isZheng)
            {
                return Azimuth.Up;
            }
            else
            {
                return Azimuth.Down;
            }
        }
        else
        {
            if (isShun)
            {
                return Azimuth.Right;
            }
            else
            {
                return Azimuth.Left;
            }
        }



        Debug.DrawLine(transform.position, transform.position + cross.normalized * 2, Color.yellow);
        Debug.DrawLine(transform.position, transform.position + dic.normalized * 2, Color.blue);
        Debug.DrawLine(transform.position, transform.position + transform.up * 2, Color.green);
    }

    void ChangeAzimuth(Azimuth azimuth)
    {
        Vector2 b = new Vector2(other.transform.localScale.x, other.transform.localScale.z);


        Vector2 offset = new Vector2((other.transform.localScale.x / (1 / b.x) * 2), (other.transform.localScale.z / (1 / b.y) * 2));

        Vector2 added = new Vector2(Mathf.Pow((1 / b.x) / 2, 2), Mathf.Pow((1 / b.y) / 2, 2));

        Debug.Log(added);
        Vector3 newPos = Vector3.zero;

        switch (azimuth)
        {
            case Azimuth.UpperLeft:
                newPos = new Vector3(-offset.x * added.x + other.transform.localScale.x / 2, offset.y * added.y - other.transform.localScale.z / 2, other.transform.localPosition.z);
                break;
            case Azimuth.UpperRight:
                newPos = new Vector3(offset.x * added.x - other.transform.localScale.x / 2, offset.y * added.y - other.transform.localScale.z / 2, other.transform.localPosition.z);
                break;
            case Azimuth.LowerLeft:
                newPos = new Vector3(-offset.x * added.x + other.transform.localScale.x / 2, -offset.y * added.y + other.transform.localScale.z / 2, other.transform.localPosition.z);
                break;
            case Azimuth.LowerRight:
                newPos = new Vector3(offset.x * added.x - other.transform.localScale.x / 2, -offset.y * added.y + other.transform.localScale.z / 2, other.transform.localPosition.z);
                break;
            case Azimuth.Left:
                newPos = new Vector3(-offset.x * added.x + other.transform.localScale.x / 2, 0 , other.transform.localPosition.z);
                break;
            case Azimuth.Right:
                newPos = new Vector3(offset.x * added.x - other.transform.localScale.x / 2, 0 , other.transform.localPosition.z);
                break;
            case Azimuth.Up:
                newPos = new Vector3(0 , offset.y * added.y - other.transform.localScale.z / 2, other.transform.localPosition.z);
                break;
            case Azimuth.Down:
                newPos = new Vector3(0 , -offset.y * added.y + other.transform.localScale.z / 2, other.transform.localPosition.z);
                break;
            default:
                break;
        }

        other.transform.localPosition = newPos;

    }

    int index = (int)Azimuth.UpperLeft;
    void OnGUI()
    {
        GUIStyle style = new GUIStyle();
        style.fontSize = 40;
        style.normal.textColor = Color.white;

        GUIStyle style2 = new GUIStyle();
        style2.fontSize = 20;
        style2.normal.textColor = Color.white;
        style2.border = new RectOffset(3,3,2,2);

        GUI.Label(new Rect(30, 10, 100, 200), dot.ToString(), style);
        GUI.Label(new Rect(30, 50, 100, 200), dot_angle.ToString(), style);
        GUI.Label(new Rect(30, 100, 100, 200), cross.ToString(), style);
        GUI.Label(new Rect(30, 300, 100, 200), fangwei.ToString(), style);
        GUI.skin.button.fontSize = 30;
        GUI.skin.button.fixedWidth = 250f;
        GUI.skin.button.fixedHeight = 100f;

        bool isClick =  GUI.Button(new Rect(30, 400, 100, 200), m_Azimuth.ToString());
        if(isClick)
        {
            if(index > (int)Azimuth.Down)
            {
                index = (int)Azimuth.UpperLeft;
            }
            m_Azimuth = (Azimuth)index;
            ChangeAzimuth(m_Azimuth);
            index++;

            Debug.Log(m_Azimuth.ToString());
        }
    }
}

因为摄像机的角度而做相应的变化这块还没有做。所以目前上面的功能只支持 “Inspector”面板中 Rotation 为 (0,0,0)的摄像机。

因为自己项目原因相机 Rotation 成 (90,0,0)。所以代码做了改变,如下面所展示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class JudgmentDirection : MonoBehaviour
{
    public GameObject other;

    float dot;
    float dot_angle;
    Vector3 cross;

    bool isZheng = false;
    bool isShun = false;

    public Azimuth m_Azimuth;

    Azimuth fangwei;


    private void Update()
    {
        if (other)
        {
            fangwei = GetAzimuth(other.transform);
        }
    }


    Azimuth GetAzimuth(Transform other)
    {
        Vector3 dic = other.transform.position - transform.position;

        dot = Vector3.Dot(dic.normalized, transform.forward.normalized);
        dot_angle = Mathf.Acos(dot) * Mathf.Rad2Deg;

        isZheng = (Mathf.Sign(dot) == -1) ? false : true;

        cross = Vector3.Cross(dic.normalized, transform.forward.normalized);
        isShun = (cross.y >= 0) ? true : false;

        float maxValue = Mathf.Cos(45.0f * Mathf.Deg2Rad);

        Debug.Log(maxValue);

        Debug.DrawLine(transform.position, transform.position + cross.normalized * 20, Color.yellow);
        Debug.DrawLine(transform.position, transform.position + dic.normalized * 20, Color.blue);
        Debug.DrawLine(transform.position, transform.position + transform.forward.normalized * 20, Color.green);

        if (Mathf.Abs(dot) > maxValue)
        {
            if (isZheng)
            {
                return Azimuth.Up;
            }
            else
            {
                return Azimuth.Down;
            }
        }
        else
        {
            if (isShun)
            {
                return Azimuth.Left;
            }
            else
            {
                return Azimuth.Right;
            }
        }
    }

    void ChangeAzimuth(Azimuth azimuth)
    {
         Vector2 b = new Vector2(other.transform.localScale.x, other.transform.localScale.z);

        Vector2 offset = new Vector2((other.transform.localScale.x / (1 / b.x) * 2), (other.transform.localScale.z / (1 / b.y) * 2));

        Vector2 added = new Vector2(Mathf.Pow((1 / b.x) / 2, 2), Mathf.Pow((1 / b.y) / 2, 2));

        Debug.Log(added);
        Vector3 newPos = Vector3.zero;

        Vector3 otherScale = other.transform.localScale;
        float fixedAixs = other.transform.localPosition.y;
        switch (azimuth)
        {
            case Azimuth.UpperLeft:
                newPos = new Vector3(-offset.x * added.x + otherScale.x / 2, fixedAixs, offset.y * added.y - otherScale.z / 2);
                break;
            case Azimuth.UpperRight:
                newPos = new Vector3(offset.x * added.x - otherScale.x / 2, fixedAixs, offset.y * added.y - otherScale.z / 2);
                break;
            case Azimuth.LowerLeft:
                newPos = new Vector3(-offset.x * added.x + otherScale.x / 2, fixedAixs, -offset.y * added.y + otherScale.z / 2);
                break;
            case Azimuth.LowerRight:
                newPos = new Vector3(offset.x * added.x - otherScale.x / 2, fixedAixs, -offset.y * added.y + otherScale.z / 2);
                break;
            case Azimuth.Left:
                newPos = new Vector3(-offset.x * added.x + otherScale.x / 2, fixedAixs, 0);
                break;
            case Azimuth.Right:
                newPos = new Vector3(offset.x * added.x - otherScale.x / 2, fixedAixs, 0);
                break;
            case Azimuth.Up:
                newPos = new Vector3(0, fixedAixs, offset.y * added.y - otherScale.z / 2);
                break;
            case Azimuth.Down:
                newPos = new Vector3(0, fixedAixs, -offset.y * added.y + otherScale.z / 2);
                break;
            default:
                break;
        }

        other.transform.localPosition = newPos;

    }

    int index = (int)Azimuth.UpperLeft;
    void OnGUI()
    {
        GUIStyle style = new GUIStyle();
        style.fontSize = 40;
        style.normal.textColor = Color.white;

        GUIStyle style2 = new GUIStyle();
        style2.fontSize = 20;
        style2.normal.textColor = Color.white;
        style2.border = new RectOffset(3, 3, 2, 2);

        GUI.Label(new Rect(30, 10, 100, 200), dot.ToString(), style);
        GUI.Label(new Rect(30, 50, 100, 200), dot_angle.ToString(), style);
        GUI.Label(new Rect(30, 100, 100, 200), cross.ToString(), style);
        GUI.Label(new Rect(30, 300, 100, 200), fangwei.ToString(), style);
        GUI.skin.button.fontSize = 30;
        GUI.skin.button.fixedWidth = 250f;
        GUI.skin.button.fixedHeight = 100f;

        bool isClick = GUI.Button(new Rect(30, 400, 100, 200), m_Azimuth.ToString());
        if (isClick)
        {
            if (index > (int)Azimuth.Down)
            {
                index = (int)Azimuth.UpperLeft;
            }
            m_Azimuth = (Azimuth)index;
            ChangeAzimuth(m_Azimuth);
            index++;

            Debug.Log(m_Azimuth.ToString());
        }
    }
}

猜你喜欢

转载自blog.csdn.net/KiTok/article/details/80338743
今日推荐