首先找到NPC资源
全选拖入Hierarchy,会自动创建好动画,重命名为Jambi,并为其添加上Box Collider 2D,为了让射线只检测到NPC,新建NPC层级,将层级设为NPC
在Hierarchy中创建UI->Image(会自动创建Canvas),再如图创建文本框,放入Canvas下方
按住ALT键点击圈中位置,使得文本框填充满图片
也可以使用吸管工具吸取游戏内颜色,使得文字更好与游戏相契合
创建脚本如下(这里发生了一个小插曲)
public class Npcmanage: MonoBehaviour
{
public GameObject dialogBox;
// Start is called before the first frame update
public void Start()
{
dialogBox.SetActive(false);
}
// Update is called once per frame
public void Update()
{
}
public void DisplayDialog()
{
dialogBox.SetActive(true);
}
}
在控制主角的脚本里写上:
if(Input.GetKeyDown(KeyCode.E))
{
RaycastHit2D hit = Physics2D.Raycast(rigidbody2d.position + Vector2.up * 0.2f, lookDirection, LayerMask.GetMask("NPC"));
if(hit.collider!=null)
{
Npcmanage npcDialog=hit.collider.GetComponent<Npcmanage>();
if(npcDialog!=null)
{
npcDialog.DisplayDialog();
}
}
}
运行后发现按E无法弹出对话框,于是插入两行测试
if(Input.GetKeyDown(KeyCode.E))
{
RaycastHit2D hit = Physics2D.Raycast(rigidbody2d.position + Vector2.up * 0.2f, lookDirection, LayerMask.GetMask("NPC"));
if(hit.collider!=null)
{
Debug.Log("hit.collider is effect");
Npcmanage npcDialog=hit.collider.GetComponent<Npcmanage>();
if(npcDialog!=null)
{
Debug.Log("npcDialog is exit");
npcDialog.DisplayDialog();
}else{
Debug.Log("npcDialog is not exit");
}
}
}
结果输出:
hit.collider is effect
npcDialog is not exit
说明npcDialog获取到的内容为空!(这让我百思不得其解,浪费了许多时间)
于是我创建了一个新的空脚本Test,并将其挂载在NPC上
在主角的脚本的Start上来调用
public Test ts;
ts=GetComponent<Test>();
if(ts!=null)
{
Debug.Log("ts is exit");
}
并没有任何结果
于是我试着获取一个任何物体都具有的组件Transform
Transform tf=GetComponent<Transfoem>();
if(tf!=null)
{
Debug.Log("tf is exit");
}
这次却如期输出了
说明问题还是出在GetComponent没法获取到Npcmanage类
于是我想到用GameObject.Find来获取游戏物体,看看从游戏物体上能不能调到这个脚本
GameObject obj=GameObject.Find("Jambi");
Npcmanage npcDialog=obj.GetComponent<Npcmanage>();
if(npcDialog!=null)
{
Debug.Log("npc is exit");
}
结果果然获取到了
于是我看看这个hit.colider是不是所谓的Jambi
GameObject obj = GameObject.Find("Jambi");
if(hit.collider==obj)
{
Debug.Log("hit.collider是Jambi");
}
结果并没有输出
说明射线碰到的物体根本不是Jambi,怪不得调不到它身上的脚本!
此时我还不知道好好看下前面的代码,不停的调层级,测试,(浪费了半小时)终于。。。
发现原来是Raycast函数少打了个参数,因为函数重载,所以没有报错。。。。。。
最后正确代码应该是
if(Input.GetKeyDown(KeyCode.E))
{
RaycastHit2D hit = Physics2D.Raycast(rigidbody2d.position + Vector2.up * 0.2f, lookDirection,1.5f, LayerMask.GetMask("NPC"));
if(hit.collider!=null)
{
Npcmanage npcDialog = hit.collider.GetComponent<Npcmanage>();
if (npcDialog != null)
{
npcDialog.DisplayDialog();
}
}
}
接下来还要完善对话框过段时间消失的功能,将Npcmanage稍微修改
public class Npcmanage: MonoBehaviour
{
public GameObject dialogBox;
public float displayTime = 4.0f;
private float timeDisplay;
// Start is called before the first frame update
public void Start()
{
dialogBox.SetActive(false);
timeDisplay = -1;
}
// Update is called once per frame
public void Update()
{
if (timeDisplay >= 0)
{
timeDisplay -= Time.deltaTime;
if(timeDisplay<0)
{
dialogBox.SetActive(false);
}
}
}
public void DisplayDialog()
{
timeDisplay = displayTime;
dialogBox.SetActive(true);
}
}
现在就大功告成了。