毕业设计-关于Unity相关小知识(1)

本文介绍了在Unity3D中实现物体跟随视角移动的三种方法,包括直接位置更新、物理射线和子物体跟随。同时,讲解了如何为物体添加多个材质球并根据碰撞情况切换显示。此外,还探讨了单例模式在控制多个对象同步行为中的应用,以避免重复计算和简化管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一)物体在视角中并跟随视角移动的效果

例:对准左上角的葡萄UI,按下GrabGrip键,获取到葡萄Icon,葡萄Icon会跟随视角移动。
在这里插入图片描述
在这里插入图片描述

1.物体.position=手柄.position+Offset,并且一直Update
//这个脚本挂LeftController中,就是左手手柄
public class myLaser : MonoBehaviour
{

  private GameObject icon;			//要显示在玩家视角的Icon
  public GameObject iconPerfab;      //Icon预制体
  public float offset;				//Icon在视角前面的距离
  public float iconScale;				//Icon的Scale
  
  void Start()
  {
     icon = Instantiate(IconPerfab);
     icon.transfrom.localScale=new Vector3(iconScale,iconScale,iconScale);
        
  }
    
  void Update()
  {
  	//Icon的位置
    icon.transfrom.position=new Vector3(
    transform.position.x,
    transform.positon.y,
    transform.position.z+Offset);
  }
  
  ...
  
}

但运行后Icon.position.z会一直+offset,Icon一直移动,并不是静止不动的效果。

2.采用物理射线Ray

参考了SteamVR_LaserPointer的做法

//这个脚本挂LeftController中,就是左手手柄
public class myLaser : MonoBehaviour
{

  private GameObject icon;			//要显示在玩家视角的Icon
  public GameObject iconPerfab;      //Icon预制体
  public float offset;				//Icon在视角前面的距离
  public float iconScale;				//Icon的Scale
    
  void Start()
  {
     Icon = Instantiate(IconPerfab);      
  }
    
  void Update()
  {
  	//物理射线raycast,射线从手柄发射
  	Ray raycast = new Ray(transform.position, transform.forward);	
    RaycastHit hit;
    bool bHit = Physics.Raycast(raycast, out hit, 100, Mask);
		
	//Icon会出现在射线的终点
	Icon.transform.position=hit.point;

	//当射线射到有碰撞盒的物体,并且物体的名字为Targect时,显示Icon
	if(bHit&&hit.collider.gameObject.name=="Targect")
	{
		Icon.SetActive(true);
	}

  }
  
  ...
  
}

此时Icon会静止出现了,但前提是一定要射到有collider的物体才会显示,有局限性。

3.将Icon作为手柄的子物体
//这个脚本挂LeftController中,就是左手手柄
public class myLaser : MonoBehaviour
{

  private GameObject icon;			//要显示在玩家视角的Icon
  public GameObject iconPerfab;      //Icon预制体
  public float offset;				//Icon在视角前面的距离
  public float iconScale;				//Icon的Scale
    
  void Start()
  {
     Icon = Instantiate(IconPerfab);
     Icon.transform.position = new Vector3(
     transform.position.x,
     transform.position.y,
     transform.position.z + offset);
     Icon.transform.parent = transform;
     Icon.transform.localScale = new Vector3(iconScale, iconScale, iconScale);  
     Icon.SetActive(false);    
  }
    
  void Update()
  {

	//当射线射到有碰撞盒的物体,并且物体的名字为Targect时,显示Icon
	//Icon一直朝向镜头
	if(bHit&&hit.collider.gameObject.name=="Targect")
	{
		Icon.SetActive(true);
		Icon.GetComponent<Transform>().LookAt(transform);
	}
  }
  
  ...
  
}

Icon作为手柄的子物体,将跟随手柄的移动而移动,从而达到图中的效果。

二)为一个物体添加多个材质球materials

例:葡萄Icon碰到草地会显示正常颜色,没有碰到则显示灰白色。
在这里插入图片描述
在这里插入图片描述

1.在Insepctor面板中添加material

在这里插入图片描述

2.脚本中调用
//这个脚本挂LeftController中,就是左手手柄
public class myLaser : MonoBehaviour
{

  private Material[] materialGroup;			//存放material的数值
  public GameObject grapeIcon;				//改变material的对象
  void Start()
  {
  	//注意,这里是materials,即是获取目标带有的全部material
     materialGroup=grapeIcon.GetComponent<MeshRenderer>().materials;
  }
    
  void Update()
  {
  	 if (bHit && hit.collider.gameObject.name != "plane")
  	 {
  	 	//从Insepctor得知,数组第二个元素是灰白色material
  	 	//注意,这里是material,没有带s
  	 	grapeIcon.GetComponent<MeshRenderer>().material = materialGroup[1];
  	 }
  	 
  	 if(bHit && hit.collider.gameObject.name == "plane")
  	 {
  	 	//若碰到地面则是正常颜色
  	 	grapeIcon.GetComponent<MeshRenderer>().material = materialGroup[1];
  	 }
  


  }
  
  ...
  
}

三)单例的使用

例:有一个类MyPlane,它是一个植物生长的脚本,grow()函数控制植物生长;另一个类DayTime,它记录游戏内共度过了多少天的天数,dayTime变量记录天数;当dayTime++后,调用grow()函数。使用接口调用会遇到一下问题:①植物是到游戏后期才能创建的,也就是说不能在DayTime类中new一个MyPlane对象(public GameObject myPlane=MyPlane的GameObject)。②A植物在12点创建,B植物在6点创建,AB植物创建的时间不同,计算的时间也不同,使用GameObejct.getComponent().grow()会导致多且重复的判断语句,而且一旦植物数量多了,也不方便处理。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值