主要达到效果:
1、箭头的指向,身体的长短
2、箭头的身体是不断向前流动的
3、箭头的头部以及尾部接近透明,并且在接入目标时会出现聚焦环
场景搭建:
创建脚本Arrow挂载在Canvas上,创建ArrowBody挂载在body上。
脚本:
Arrow:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
/// <summary>
/// 箭头的主题,用于控制箭头的显示、隐藏和指向
/// </summary>
public class Arrow : MonoBehaviour {
Vector3 origin; //起点
public GameObject jiantou; //箭头对象
public GameObject ring; //圆环
public RectTransform rect; //节点父组件
GraphicRaycaster graphicRaycaster;
EventSystem eventSystem;
List<RaycastResult> list = new List<RaycastResult>();
void Start () {
graphicRaycaster = GetComponent<GraphicRaycaster>();
}
void Update () {
PointerEventData eventData = new PointerEventData(eventSystem);//与指针(鼠标/触摸)事件相关的事件负载。(PointerEventData)
eventData.pressPosition = Input.mousePosition;
eventData.position = Input.mousePosition;//当前指针位置。
graphicRaycaster.Raycast(eventData, list);//如同Physics.Raycast(ray, out hit)绑定相应的射线检测信息
//点下鼠标左键
if (Input.GetMouseButtonDown(0))
{
origin = Input.mousePosition;
jiantou.transform.position = Input.mousePosition;
if (list.Count > 0)
{
foreach (RaycastResult result in list)
{
if (result.gameObject.tag == "target")
{
jiantou.SetActive(true);
}
}
}
}
//一直按住鼠标左键
if (Input.GetMouseButton(0))
{
jiantou.transform.up = (Input.mousePosition - origin);
jiantou.transform.position = Input.mousePosition;
rect.sizeDelta = new Vector2(rect.rect.width, Vector3.Distance(Input.mousePosition, origin));
if (list.Count > 0)
{
foreach (RaycastResult result in list)
{
if (result.gameObject.tag == "self")
{
ring.SetActive(true);
}
else
{
ring.SetActive(false);
}
}
}
else
{
ring.SetActive(false);
}
}
//释放鼠标左键
if (Input.GetMouseButtonUp(0))
{
list.Clear();
ring.SetActive(false);
jiantou.SetActive(false);
}
}
}
ArrowBody:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 箭头的身体,主要用于控制箭头身体中节点的移动和透明度
/// </summary>
public class ArrowBody : MonoBehaviour {
int numIndex;
RectTransform localTransform;
[Range(20,1000)]
public float flowSpeed = 10f; //流动速度
/// <summary>
/// 临时的Node节点
/// </summary>
Transform tempNodeTfm;
void Start () {
localTransform = GetComponent<RectTransform>();
}
void Update () {
for (int i = 0; i < transform.childCount; i++)
{
tempNodeTfm = transform.GetChild(i);
tempNodeTfm.localPosition = new Vector3(0, tempNodeTfm.localPosition.y + Time.fixedDeltaTime * flowSpeed, 0);
numIndex = (int)localTransform.rect.height / 80;
//箭头体内子节点的透明度显示
if (i <= numIndex * 0.3f)
{
tempNodeTfm.GetComponent<Image>().color = Color.Lerp(tempNodeTfm.GetComponent<Image>().color, new Color(1, 1, 1, (70 * i + 60) / 255f), Time.fixedDeltaTime * 6f);
}
else if (i >= numIndex * 0.7f)
{
tempNodeTfm.GetComponent<Image>().color = Color.Lerp(tempNodeTfm.GetComponent<Image>().color, new Color(1, 1, 1, (70 * (numIndex - i) + 60) / 255f), Time.fixedDeltaTime * 6f);
}
else
{
tempNodeTfm.GetComponent<Image>().color = Color.white;
}
//箭头体内子节点的循环移动
if (tempNodeTfm.localPosition.y > 40)
{
tempNodeTfm.localPosition = new Vector3(0, transform.GetChild(transform.childCount - 1).localPosition.y - 80, 0f);
tempNodeTfm.SetAsLastSibling();
}
}
}
}
效果:
参考:https://blog.csdn.net/qq_26276097/article/details/75453351
扫描二维码关注公众号,回复:
6476232 查看本文章