unity3D游戏开发实战(三)——射线检测与物体交互
目录交互交互方式物体响应代码交互检测代码UI准心交互消息Inspector参数道具测试交互交互方式上一次我们完成了道具类的编写,但是消耗与获得道具的交互脚本还仅限于碰撞产生光照,因此我们这次要完善一下交互代码。鼠标移动用来控制视野方向,所以我们用鼠标左键点击来模拟交互,在鼠标点击后使用射线检测与前方物体交互。而物体对于交互的响应虽然有各种形式,但是其可以具体分成几个大类——生成物体,销毁物体,获得
交互
交互方式
上一次我们完成了道具类的编写,但是消耗与获得道具的交互脚本还仅限于碰撞产生光照,因此我们这次要完善一下交互代码。
鼠标移动用来控制视野方向,所以我们用鼠标左键点击来模拟交互,在鼠标点击后使用射线检测与前方物体交互。
而物体对于交互的响应虽然有各种形式,但是其可以具体分成几个大类——生成物体,销毁物体,获得道具,道具交换,使用道具。
很明显前两种之一可以和后三种之一共存,于是我们只需要留好扩展代码块,按照几个大类对其处理即可。
物体响应代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BeContacted : MonoBehaviour
{
[Range(0,3)]
public int objectType; //0为给予道具,1为交换道具,2为消耗道具,3为机关类
public int needItem;
public int[] giveItem;
public GameObject[] showGameObject;
public GameObject[] clearGameObject;
public GameObject messageShower;
public string successMessage;
public string falseMessage;
private Item item;
private void Start()
{
item = GameObject.Find("ItemManager").GetComponent<Item>();
}
public void Contact()
{
switch (objectType)
{
case 0:
foreach(int i in giveItem)
{
item.AddItem(i);
}
ObjectChange();
messageShower.SendMessage("ShowMsg", successMessage);
tag = "Touched";
break;
case 1:
if (item.GetItem() != needItem)
{
messageShower.SendMessage("ShowMsg", falseMessage);
break;
}
item.UseItem();
ObjectChange();
foreach (int i in giveItem)
{
break;
}
messageShower.SendMessage("ShowMsg", successMessage);
tag = "Touched";
break;
case 2:
if (item.GetItem() != needItem)
{
messageShower.SendMessage("ShowMsg", falseMessage);
break;
}
item.UseItem();
ObjectChange();
tag = "Touched";
break;
case 3:
ObjectChange();
messageShower.SendMessage("ShowMsg", successMessage);
tag = "Touched";
break;
default:
break;
}
}
private void ObjectChange()
{
foreach (GameObject obj in showGameObject)
obj.SetActive(true);
foreach (GameObject obj in clearGameObject)
Destroy(obj);
}
}
无论物体是否生成或销毁物体,我们都调用ObjectChange来对数组中的待生成/销毁物体做遍历,如果无此需求为空即可。
而关于道具的变动则分为四类,得到,交换,使用,不变,对于这四类分别编写对应代码,因为我们之前在Item中已经充分做好了Add和Use的代码编写,这里只需要调用函数即可。
交互检测代码
我们还需要在操作物体移动的脚本的Update函数中加入如下几行:
if (Input.GetMouseButtonDown(0))
{
if (Physics.Raycast(sight.transform.position, sight.transform.forward, out contact, 5f))
{
if (contact.transform.CompareTag("Untouched"))
contact.transform.gameObject.SendMessage("Contact");
}
}
其中,contact的类型为RaycastHit,需要我们提前声明在代码顶部,在检测到点击物体为Untouched标签后,便调用其Contact函数,同时Contact函数会改变标签为Touched,来防止一个物体反复交互。
UI
准心
因为我们的游戏多了鼠标点击的功能,让玩家知道自己的点击会在哪里生效十分重要,我们要做的也十分简单,在UI界面正中心添加一个准心。
在UIInGame画布中添加Image,按图中设置调整参数,之后放上自己画好的准星图片,我们的准心就做好了。
交互消息
相信刚才有读者注意到,在交互代码中有几个地方调用了叫做“ShowMsg”的函数,这个函数是做什么用的呢?
因为玩家不一定总能做出正确的操作,所以我们需要在玩家进行错误操作时进行提醒,或者在进行正确操作时告知玩家操作结果,因此需要在屏幕上打印相应的信息。
而打印方式也十分简单,提前做好消息预制体,之后在需要打印消息时生成相应的实例即可。
以下为两个脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Message : MonoBehaviour
{
public GameObject textObj;
public float spanTime;
public Transform startPos;
private Text text;
private Queue<string> msgs = new Queue<string>();
private float lastShow = 0;
private void Start()
{
text = textObj.GetComponent<Text>();
}
private void Update()
{
if (msgs.Count > 0)
{
if (Time.time - lastShow >= spanTime)
{
text.text = msgs.Dequeue();
Instantiate(textObj,startPos).transform.SetParent(transform);
lastShow = Time.time;
}
}
}
public void ShowMsg(string s)
{
msgs.Enqueue(s);
}
}
这是挂载在场景中MessageManager上的一个脚本,通过队列的方式来解决多条消息并发问题,并加入最低响应间隔,防止玩家快速按下交互导致消息连续发出。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MsgTextAnimator : MonoBehaviour
{
public float moveSpeed;
public float fadeSpeed;
private Text text;
private void Start()
{
text = GetComponent<Text>();
}
void Update()
{
transform.Translate(new Vector3(0, moveSpeed * Time.deltaTime, 0));
text.color -= new Color(0, 0, 0, fadeSpeed * Time.deltaTime);
if (text.color.a <= 0)
Destroy(gameObject);
}
}
这是挂载在消息预制体上的脚本,文字生成后向上移动变淡至消失,透明度为0时销毁减少无用计算消耗。
Inspector参数
我们将刚刚编写的交互脚本挂载在初始房间的cube上,并改变参数如下:
让我们来看看实现的效果:
消息按照预期出现并消失,方块上的光照也顺利出现,再次按下左键也不会再有后续响应。
道具测试
但我们的脚本编写还涉及道具消耗这部分,因此我们稍微修改cube上的数值进行测试。
在道具栏为钥匙和空瓶的时候按下点击都没有反应,在道具栏为水瓶时点击,水瓶消耗,也顺利发生响应,道具和响应代码宣告成功,接下来就是关卡的正式设计了。
更多推荐
所有评论(0)