接上篇 上篇实现了点餐的功能
但是我想要的效果是 可以控制每一个顾客去柜台点餐
之后再厨房做出来之后 我们顾客被柜台呼叫
然后自己去前台取餐
这篇博客我们实现一下顾客的移动的方法
基于这篇进行修改的父类和子类
还是老规矩 再给出demo
看似简单的一个demo 我们需要考虑几个问题
1.点击之后怎么取消其他顾客的点击
2.如何实现顾客的缓动(插值?)
3.如何实现点击
开发过程
点击容易实现 使用射线 既方便又不容易出错
之前写的一篇关于射线简单的使用地址
给大家参考
我这里专门写了一个顾客的管理器 为了很好的管理顾客
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.SymbolStore;
using TreeEditor;
using UnityEngine;
public class UserManager : MonoBehaviour
{
//顾客管理器
public List<User> UserList;
private Transform UserGroup;//顾客族群
public static UserManager Instance;
private void Awake()
{
Instance = this;
}
private void Start()
{
UserGroup = GameObject.Find("UserGroup").GetComponent<Transform>();
User[] users = UserGroup.GetComponentsInChildren<User>();
foreach(var a in users)
{
UserList.Add(a);
}
//全部顾客通过代码添加到群组中
}
/// <summary>
/// 检查所有的isMe
/// </summary>
public void CheakAllisMe(string UserTag)
{
foreach(var a in UserList)
{
if (UserTag != a.UserTag)
{
a.isMe = false;
}
else
{
a.isMe = true;
}
}
}
}
为了降低耦合度 我大部分通过代码赋值 这样在unity里能避免很多没有赋值的问题
之后实现顾客的移动 我现在了User(父类)上
我直接把整体代码给大家 免得还得返回去看
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.PlayerLoop;
using UnityEngine.UI;
public class User : MonoBehaviour
{
//此类为所有顾客的父类
public ChinarDelegate Cd; //委托对象
protected Text temporaryText; //临时文本,设置公有静态是为了 方便调用颜色属性,去改变服务员文本颜色
private Vector3 startpos;
private Transform TalkFoodPosi;
protected float timer;
protected bool ismove;
public string UserTag;//每个顾客专属标签
public bool isMe = false;//是不是点击了自己
private bool isRun=false;
private Ray ray;
private RaycastHit hit;
public virtual void Start()
{
startpos = transform.position;
Cd = GameObject.Find("Shopper").GetComponent<ChinarDelegate>(); //获取对象
Cd.callNumber += LookScreen;
TalkFoodPosi = GameObject.Find("talkPosi").transform;
}
/// <summary>
/// 抬头看大屏幕
/// </summary>
public virtual void LookScreen()
{
//temporaryText.text = "顾客C看向大屏幕";
StopCoroutine(ClearText());
StartCoroutine(ClearText());
}
/// <summary>
/// 清理文本内容
/// </summary>
/// <returns></returns>
protected IEnumerator ClearText()
{
yield return new WaitForSeconds(3);
temporaryText.text = "";
}
protected virtual void Update()
{
if (ismove)
{
timer += Time.deltaTime * 0.5f;
}
else
{
timer -= Time.deltaTime * 0.5f;
}
if (timer > 1f)
{
ismove = false;
}
if (timer <= 0)
{
timer = 0;
}
//gameObject.transform.position = Vector3.Lerp(startpos, TalkFoodPosi.position, timer);
FollowMouse();
}
private void FollowMouse()
{
if (Input.GetMouseButtonDown(0)&&isMe)
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
isRun = Physics.Raycast(ray, out hit, 1000);
}
if (isRun)
{
transform.position =
Vector3.MoveTowards(transform.position,
new Vector3(hit.point.x,transform.position .y,hit.point .z),
Time.deltaTime * 20);
}
if (transform.position == hit.point)
{
isRun = false;
}
}
}
顾客一
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UserOne : User
{
public override void Start()//重写实例化
{
base.Start();
temporaryText = GameObject.Find("customtalk1").GetComponent<Text>();
}
public override void LookScreen()//重写看大屏幕
{
base.LookScreen();
temporaryText.text = "顾客A看向大屏幕";
}
protected override void Update()
{
base.Update();
MouseClickUser();
}
/// <summary>
/// 鼠标点击顾客的方法
/// </summary>
protected virtual void MouseClickUser()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 1000))
{
if (hit.collider.tag == UserTag)
{
UserManager.Instance.CheakAllisMe(UserTag);
}
}
}
}
顾客二
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UserTwo : User
{
public override void Start()
{
base.Start();
Cd.someFood += WaitHamburger;
temporaryText = GameObject.Find("customtalk2").GetComponent<Text>();
}
/// <summary>
/// 服务员叫汉堡时,委托事件才会触发
/// </summary>
public bool WaitHamburger(string food)
{
if (food == "汉堡")
{
temporaryText.text = "这里,我要汉堡";
ismove = true;
StopCoroutine(ClearText());
StartCoroutine(ClearText());
return true;
}
return false;
}
public override void LookScreen()
{
base.LookScreen();
temporaryText.text = "顾客B看向大屏幕";
}
protected override void Update()
{
base.Update();
MouseClickUser();
}
/// <summary>
/// 鼠标点击顾客的方法
/// </summary>
protected virtual void MouseClickUser()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 1000))
{
if (hit.collider.tag == UserTag)
{
UserManager.Instance.CheakAllisMe(UserTag);
}
}
}
}
顾客三
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UserThree : User
{
public override void Start()//重写实例化
{
base.Start();
temporaryText = GameObject.Find("customtalk3 ").GetComponent<Text>();
//当 叫号的委托对象中,有多个方法调用时,需要用 += 添加
Cd.someFood += WaitCola;
//委托对象添加 顾客3的可乐
}
public override void LookScreen()//重写看大屏幕
{
base.LookScreen();
temporaryText.text = "顾客C看向大屏幕";
}
/// <summary>
/// 服务员叫可乐时,委托事件才会触发
/// </summary>
public bool WaitCola(string food)
{
if (food == "可乐")
{
temporaryText.text = "这里,我要的可乐";
ismove = true;
StopCoroutine(ClearText());
StartCoroutine(ClearText());
return true;
}
return false;
}
protected override void Update()
{
base.Update();
MouseClickUser();
}
/// <summary>
/// 鼠标点击顾客的方法
/// </summary>
protected virtual void MouseClickUser()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 1000))
{
if (hit.collider.tag == UserTag)
{
UserManager.Instance.CheakAllisMe(UserTag);
}
}
}
}
场景的搭建 我一直没细说 大家自行搭建
如果有什么问题可以联系我
主页有我的联系方式 (知无不答)