赞
踩
在C#中提供的很好的类型转换方式总结为:
Object => 已知引用类型——使用as操作符完成;
Object => 已知值类型——先使用is操作符来进行判断,再用类型强转换方式进行转换;
已知引用类型之间转换——首先需要相应类型提供转换函数,再用类型强转换方式进行转换;
已知值类型之间转换——最好使用系统提供的Conver类所涉及的静态方法。
在调用Instantiate()方法使用prefab创建对象时,接收Instantiate()方法返回值的变量类型必须和声明prefab变量的类型一致,否则接收变量的值会为null.
比如说,我在脚本里面定义:
public GameObject myPrefab;
那么在使用这个myPrefab做Instantiate()的时候,接收返回值变量的类型也必须是GameObject,如下:
GameObject newObject = Instantiate(myPrefab) as GameObject;
注意Instantiate()后面的as也要是GameObject。
又比如我们的prefab类型是我们自定义的UserObject
public UserObject prefab;
那么在使用Instantiate()时我们需要写成:
UserObject newObject = Instantiate(myPrefab) as UserObject;
比较容易犯的一个错误是我们声明的类型是:
public GameObject myPrefab;
在Instantiate()返回值却想要用Transform,如下:
Transform newObject = Instantiate(myPrefab) as Transform;
这个时候就会出现newObject为null的问题。
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class TankAttack : MonoBehaviour
- {
- public GameObject shellPrefab; //子弹预制体
- public KeyCode fireKey = KeyCode.Space; //发射键,默认空格space键
- private Transform firePosition; //子弹发射位置
- public float shellSpeed = 15f; //子弹速度
-
- // Start is called before the first frame update
- void Start()
- {
- firePosition = transform.Find("FirePosition");
- }
-
- // Update is called once per frame
- void Update()
- {
- if (Input.GetKeyDown(fireKey))
- {
- //GameObject.Instantiate为实例化元素,3个参数分别为 要实例化的预制体,实例化的位置,实例化的方向
- GameObject go = GameObject.Instantiate(shellPrefab, firePosition.position, firePosition.rotation) as GameObject; //用GameObject类型接收,所以用as进行类型转换
- //子弹的飞行速度和方向
- go.GetComponent<Rigidbody>().velocity = go.transform.forward * shellSpeed;
- }
- }
- }
1.触发条件
2.代码调试
- private void OnTriggerEnter(Collider other)
- {
- Debug.Log(message:other.name);//获取gameobject的名字
- other.transform.position+= new Vector3(0, 0.44f, 0);//gameobject的y坐标发生变化。
- }
3.触发分主动与被动
- OnTriggerEnter(Collider other)与OntriggerStay(Collider other)的形参为被动的gameobject。
- 假设:ObjectA为设置为Is Trigger的一方,
- ObjectB为接触的另一方。
- 情况1:当ObjectA主动接触ObjectB,形参other为ObjectB.
- 情况2:当ObjectB主动接触ObjectA,形参other为ObjectA。
Play On Awake:实例化后自动播放
创建Shell脚本,用于炮弹的碰撞事件
脚本挂载在Shell预制体上
Shell预制体的 Capsule Collider 属性的 Is Trigger 设置为开启状态,这样会与其它网格发生碰撞(碰撞后如不发生事件则直接穿透)
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class Shell : MonoBehaviour
- {
-
- public GameObject ShellExplosionPrefab; //子弹爆炸效果的预制体
- // 脚本写完后,把做好的ShellExplosion预制体,挂在Shell预制体Shell脚本的ShellExplosionPrefab中
-
- // Start is called before the first frame update
- void Start()
- {
-
- }
-
- // Update is called once per frame
- void Update()
- {
-
- }
-
- // 子弹发生碰撞时效果
- private void OnTriggerEnter(Collider other)
- {
- // 实例化爆炸效果,当前位置,当前方向
- GameObject.Instantiate(ShellExplosionPrefab, transform.position, transform.rotation);
- // 把自身销毁
- GameObject.Destroy(this.gameObject);
- }
- }
创建脚本DestroyForTime,挂在预制体ShellExplosion上
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class DestroyForTime : MonoBehaviour
- {
-
- public float time = 1.5f; // 生存时间(设置动画时长)
-
- // Start is called before the first frame update
- void Start()
- {
- Destroy(this.gameObject, time); //预制体被实例化后,在time时间长度后销毁自身
- }
-
- // Update is called once per frame
- void Update()
- {
-
- }
- }
先新增一个Tag:Tank,然后给Tank对象添加Tag属性为Tank,这样当炸弹碰撞的物体Tag属性是Tank时就是遇坦克发生碰撞,然后修改相关的属性等
Shell脚本修改为:
- public class Shell : MonoBehaviour
- {
-
- public GameObject ShellExplosionPrefab; //子弹爆炸效果的预制体
-
- // Start is called before the first frame update
- void Start()
- {
-
- }
-
- // Update is called once per frame
- void Update()
- {
-
- }
-
- // 子弹发生碰撞时效果
- private void OnTriggerEnter(Collider other)
- {
- // 实例化爆炸效果,当前位置,当前方向
- GameObject.Instantiate(ShellExplosionPrefab, transform.position, transform.rotation);
- // 把自身销毁
- GameObject.Destroy(this.gameObject);
- // 子弹碰撞的物体tag为Tank,说明是坦克
- if (other.gameObject.CompareTag("Tank"))
- {
- other.gameObject.SendMessage("TankDamage"); // 调用碰撞到的对象的TankDamage()方法
- }
- }
- }
新增一个TankHealth脚本,为坦克血量,挂载在坦克预制体上,所有坦克都是相同的血量属性
- public class TankHealth : MonoBehaviour
- {
-
- public int hp = 100; //坦克血量
- public GameObject tankExplosion; //坦克阵亡效果
-
- // Start is called before the first frame update
- void Start()
- {
-
- }
-
- // Update is called once per frame
- void Update()
- {
-
- }
-
- // 坦克受到伤害
- void TankDamage()
- {
- if (hp <= 0) return; // 已阵亡
- hp -= Random.Range(5, 15); //每次受到伤害损失5~15一个随机的伤害
- if (hp <= 0)
- {
- // 受到伤害后阵亡,播放坦克阵亡动画 TankExplosion
- // TankExplosion 的 Play On Awake 勾选上,被实例化后自动播放
- GameObject.Instantiate(tankExplosion, transform.position + Vector3.up, transform.rotation); // 为了效果,爆炸动画向上移动1米 + Vector3.up
- GameObject.Destroy(this.gameObject); // 销毁掉坦克自身
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。