2D UI 跟隨3D 物體(自帶縮放)

彭然心跳發表於2018-04-14

在專案中會經常遇到血條跟隨啊(要求做成2D血條),或者其他的2D UI跟隨,那麼小生現在在這裡已經寫好元件,可以供大家直接使用,直接拿到介面便可以使用了,別的不說先上程式碼

//--------------------------------------------
//            NGUI: HUD Text
// Copyright 漏 2012 Tasharen Entertainment
//--------------------------------------------

using UnityEngine;

/// <summary>
/// Attaching this script to an object will make it visibly follow another object, even if the two are using different cameras to draw them.
/// </summary>

[AddComponentMenu("NGUI/Examples/Follow Target")]
public class UIFollowTarget : MonoBehaviour
{
    /// <summary>
    /// 3D target that this object will be positioned above.
    /// </summary>

    public Transform target;

    /// <summary>
    /// Game camera to use.
    /// </summary>

    public Camera gameCamera;

    /// <summary>
    /// UI camera to use.
    /// </summary>

    public Camera uiCamera;

    /// <summary>
    /// Whether the children will be disabled when this object is no longer visible.
    /// </summary>

    public bool disableIfInvisible = true;

    Transform mTrans;
    bool mIsVisible = false;
    Vector3 pos;
    /// <summary>
    /// Cache the transform;
    /// </summary>

    void Awake () { mTrans = transform; }

    /// <summary>
    /// Find both the UI camera and the game camera so they can be used for the position calculations
    /// </summary>

    void Start()
    {
        if (target != null)
        {
            if (gameCamera == null) gameCamera = NGUITools.FindCameraForLayer(target.gameObject.layer);
            if (uiCamera == null) uiCamera = NGUITools.FindCameraForLayer(gameObject.layer);
            SetVisible(false);
        }
        else
        {
            Debug.LogError("Expected to have 'target' set to a valid transform", this);
            enabled = false;
        }
    }

    /// <summary>
    /// Enable or disable child objects.
    /// </summary>

    void SetVisible (bool val)
    {
        mIsVisible = val;

        for (int i = 0, imax = mTrans.childCount; i < imax; ++i)
        {
            NGUITools.SetActive(mTrans.GetChild(i).gameObject, val);
        }
    }

    /// <summary>
    /// Update the position of the HUD object every frame such that is position correctly over top of its real world object.
    /// </summary>

    void Update()
    {
        if (target != null)
        {
            pos = gameCamera.WorldToViewportPoint(target.position);
        }

        // Determine the visibility and the target alpha
        bool isVisible = (gameCamera.orthographic || pos.z > 0f) && (!disableIfInvisible || (pos.x > 0f && pos.x < 1f && pos.y > 0f && pos.y < 1f));

        // Update the visibility flag
        if (mIsVisible != isVisible) SetVisible(isVisible);

        // If visible, update the position
        if (isVisible)
        {
            transform.position = uiCamera.ViewportToWorldPoint(pos);
            pos = mTrans.localPosition;
            pos.x = Mathf.FloorToInt(pos.x);
            pos.y = Mathf.FloorToInt(pos.y);
            pos.z = 0f;
            mTrans.localPosition = pos;
        }
        OnUpdate(isVisible);
    }

    /// <summary>
    /// Custom update function.
    /// </summary>

    protected virtual void OnUpdate (bool isVisible) { }
}







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

public class ArchUIInfo : MonoBehaviour
{
 //上面的指令碼是NGUI外掛程式碼咯,小生我現在還沒這麼厲害寫的這麼流,這個指令碼就是我寫的元件咯
    private bool m_bInited = false;
    private UILabel m_info = null;
    private UISprite m_foreground = null;
    private Transform m_target = null;
    private const string m_strRes = "Final/UI/ArchUI/ArchUIInfo";//做好的預支體
    private static UIRoot m_root;
    private float m_Scale;//縮放比例
    void Start()
    {
        Init();
    }
    private void Init()
    {
        if (m_bInited)
            return;
        m_bInited = true;
        m_info = GetChild("Label").GetComponent<UILabel>();
        m_foreground = GetChild("Sprite").GetComponent<UISprite>();

        m_Scale = Vector3.Distance(m_target.position, Camera.main.transform.position);
    }
    void Update() 
    {
        if (m_target != null)
        {
            float newScale = m_Scale / Vector3.Distance(m_target.position, Camera.main.transform.position);
            transform.position = WorldToUI(m_target.position);
            transform.localScale = Vector3.one * (newScale * 0.3f);
        }
    }
    public void SetData(string ArchName,Transform target)
    {
        m_target = target;
        Init();
        m_info.text = ArchName;
       // m_root = GameObject.FindObjectOfType<UIRoot>();
        UIFollowTarget m_UIFollowTarget = AddComponent<UIFollowTarget>(gameObject);
        if (m_UIFollowTarget != null)
            m_UIFollowTarget.target = target;
        //Camera camera = m_root.GetComponentInChildren<Camera>();
        Camera camera = transform.parent.root.GetComponentInChildren<Camera>();
        m_UIFollowTarget.uiCamera = camera;
        m_UIFollowTarget.gameCamera = Camera.main;

    }
    public static void ShowUI(BWUI ui,string ArchName, Transform target)
    {
        GameObject parent = null;
        if (ui == null)
        {
            m_root = GameObject.FindObjectOfType<UIRoot>();
            parent = m_root.gameObject;
        }
        else 
        {
            parent = ui.gameObject;
        }
        GameObject instObj = Resources.Load(m_strRes) as GameObject;
        if (instObj == null)
        {
            BwTrace.LogError("ArchUIInfo::ShowUI()...instObj:為空");
            return;
        }
        GameObject inst = NGUITools.AddChild(parent, instObj);
        if (inst == null)
        {
            BwTrace.LogError("ArchUIInfo::ShowUI()...inst:為空");
            return;
        }
        inst.name = instObj.name;

        ArchUIInfo _ArchUIInfo = inst.GetComponent<ArchUIInfo>();
        if (_ArchUIInfo == null)
          _ArchUIInfo=inst.AddComponent<ArchUIInfo>();
        _ArchUIInfo.SetData(ArchName, target);
      
    }

    private Vector3 WorldToUI(Vector3 point)
    {
        Vector3 pt = Camera.main.WorldToScreenPoint(point);
        Vector3 ff = UICamera.currentCamera.ScreenToWorldPoint(pt);
        ff.z = 0;
        return ff;
    }

    private  GameObject GetChild(string name)
    {
        if (name == "this")
            return gameObject;
        if (name == null)
            return null;
        Transform trans = gameObject.transform.Find(name);
        if (trans == null)
        {
            //Debug.LogError("gameObject.name:" + gameObject.name + ";GetChild()trans == null");
            return null;
        }
        return trans.gameObject;
    }

    private  T AddComponent<T>(GameObject obj) where T : Component
    {
        T co = obj.GetComponent<T>();
        if (co == null)
            co = obj.AddComponent<T>();
        return co;
    }


}

 

相關文章