CameraFixationManager脚本:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class CameraFixationManager : MonoBehaviour
{
///
/// 在UI上出现的点
///
public GameObject ui_point;
///
/// 射线是否撞到了有触发事件的碰撞体
///
public static bool IsImpactCollider = false;
///
/// 撞击点的位置
///
public Vector3 HitPosition = Vector3.zero;
///
/// 射线可以碰撞到的层
///
public LayerMask layerMask;
#region 事件回调
///
/// 射线进入回调
///
public Action
///
/// 射线离开的回调
///
public Action
///
/// 射线正在射中的回调
///
public Action
#endregion
///
/// 响应的标签层,所有的交互事件都需要放到该层
///
public string ResponseTag;
///
/// 是否播放音乐特效
///
public bool IsPlayAudio = true;
///
/// 射线缓冲,意思就是射线当前碰撞套的物体
///
private Transform _transform = null;
///
/// 是否碰撞到
///
protected bool IsCollider = true;
protected virtual void Awake()
{
}
///
/// 放在延迟更新是因为,输入事件一般是在Update之前,所以,处理完输入逻辑后,在 Update里判断输入状态,再在延迟更新里判断碰撞状态,这样就不用手动
/// edit/ProjectSettings/ScriptExecutionOrder的编排脚本的方法执行顺序
///
void LateUpdate()
{
if (!IsCollider) return;
RaycastHit hit;
//只能向屏幕中点发射线
var ray = GetRay();//这里进一步抽象,因为有相机注视,还有手柄射线注视
if (Physics.Raycast(ray, out hit, 1000f, layerMask))//这里把5层设置为可碰撞层,其他层都要忽略掉
{
//Debug.Log("碰撞到的物体名字是:" + hit.transform.name);
HitPosition = hit.point;//碰撞点事世界位置,切记 切记
if (ui_point)
{
ui_point.SetActive(true);
//把球体放在射线与物体的接触点
ui_point.transform.position = new Vector3(hit.point.x, hit.point.y, hit.point.z);
}
if (!hit.transform.CompareTag(ResponseTag))//如果不属于ResponseTag标签,则不进行消息触发
{
IsImpactCollider = false;
if (_transform != null)//物体离开回调
{
if (RayLeave != null)
RayLeave(_transform.gameObject);
// Debug.Log("离开了" + _transform.name);
}
_transform = null;
return;
}
IsImpactCollider = true;
//被碰撞的物体第一次进入触发回调,第二个逻辑是射线从一个物体移动到另外一个物体的判断
if (_transform == null || (_transform != hit.transform && _transform != null))
{
if (RayEnter != null)
RayEnter(hit.transform.gameObject);
// if (IsPlayAudio)
// AudioManager.Instance.PlayAudio(AudioType.RayPass);
//Debug.Log("进入了" + hit.transform.name);
if (_transform != null)
{
if (RayLeave != null)
RayLeave(_transform.gameObject);
//Debug.Log("离开了" + _transform.name);
}
_transform = hit.transform;
}
else if (_transform == hit.transform)//在进入物体的第二帧以上
{
if (RayEntering != null)
RayEntering(hit.transform.gameObject);
//Debug.Log("持续碰撞物体:" + hit.transform.name);
_transform = hit.transform;
}
}
else
{
IsImpactCollider = false;
HitPosition = Vector3.zero;
if (_transform != null)//物体离开回调
{
if (RayLeave != null)
RayLeave(_transform.gameObject);
// Debug.Log("离开了" + _transform.name);
}
_transform = null;
if (ui_point)
{
ui_point.SetActive(false);
}
}
}
protected abstract Ray GetRay();
protected virtual void OnDestroy()
{
}
}
CarRay脚本:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CarRay : CameraFixationManager
{
public GameObject RayStartingPoint;
ConditionalJudgment conditionalJudgment;
protected override Ray GetRay()
{
Ray ray = new Ray(RayStartingPoint.transform.position, RayStartingPoint.transform.forward);
return ray;
}
SetButtonEvent buttonEvent;
BackGroundEvent groundEvent;
protected override void Awake()
{
base.Awake();
RayEnter += SetBtnEnterEvent;
RayLeave += SetBtnLeaveEvent;
conditionalJudgment = FindObjectOfType
}
///
/// 射线 离开
///
///
private void SetBtnLeaveEvent(GameObject obj)
{
SetEvent(obj, false);
}
///
/// 射线进入
///
///
private void SetBtnEnterEvent(GameObject obj)
{
if (obj.name== "iphone"&&GameController.gameType==GameType.CallDriving&&GameController.IsStartGame&&conditionalJudgment.IsJudgmCallDriving)
{
print("碰到手机");
EventCenter.Broadcast(BtnEventType.BirthObstacle); //前方出现车辆
conditionalJudgment.IsJudgmCallDriving = false;
EventCenter.Broadcast(BtnEventType.OperationFailure); //前方出现车辆
return;
}
SetEvent(obj,true);
print("射线进入" + obj.name);
}
void SetEvent(GameObject obj, bool IsEnter)
{
//进入音效
if (IsEnter)
{
AudioManagement.Instance.PlayEnentBtn();
}
//按钮
buttonEvent = obj.transform.GetComponent
if (buttonEvent)
{
buttonEvent.isStartTime = IsEnter;
}
//背景
groundEvent = obj.transform.GetComponent
if (groundEvent)
{
if (IsEnter)
{
groundEvent.SetPitchImage();
}
else
{
groundEvent.SetNormalImage();
}
}
}
protected override void OnDestroy()
{
base.OnDestroy();
RayEnter -= SetBtnEnterEvent;
RayLeave -= SetBtnLeaveEvent;
}
// Update is called once per frame
void Update()
{
}
}
SetButtonEvent脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
///
/// 控制进度条以及按钮事件
///
public delegate void ButtonEventHandler();
public class SetButtonEvent : MonoBehaviour
{
public event ButtonEventHandler buttonEvent;
[HideInInspector]
public bool isStartTime;
public Image image;
void Start()
{
}
protected virtual void OnButtonEvent()
{
if (buttonEvent!=null)
{
buttonEvent.Invoke();
}
image.fillAmount = 0;
}
// Update is called once per frame
void Update()
{
if (isStartTime)
{
if (image.fillAmount != 1)
{
image.fillAmount += Time.deltaTime*0.4f;
if (image.fillAmount == 1)
{
OnButtonEvent();
isStartTime = false;
}
}
}
else
{
image.fillAmount = 0;
}
}
}
文章链接
发表评论