当前位置:   article > 正文

Unity游戏开发笔记(二)_gameobject go = gameobject.instantiate(shellprefab

gameobject go = gameobject.instantiate(shellprefab, fireposition.position, f

C#中关于as关键字的使用

在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的问题。

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class TankAttack : MonoBehaviour
  5. {
  6. public GameObject shellPrefab; //子弹预制体
  7. public KeyCode fireKey = KeyCode.Space; //发射键,默认空格space键
  8. private Transform firePosition; //子弹发射位置
  9. public float shellSpeed = 15f; //子弹速度
  10. // Start is called before the first frame update
  11. void Start()
  12. {
  13. firePosition = transform.Find("FirePosition");
  14. }
  15. // Update is called once per frame
  16. void Update()
  17. {
  18. if (Input.GetKeyDown(fireKey))
  19. {
  20. //GameObject.Instantiate为实例化元素,3个参数分别为 要实例化的预制体,实例化的位置,实例化的方向
  21. GameObject go = GameObject.Instantiate(shellPrefab, firePosition.position, firePosition.rotation) as GameObject; //用GameObject类型接收,所以用as进行类型转换
  22. //子弹的飞行速度和方向
  23. go.GetComponent<Rigidbody>().velocity = go.transform.forward * shellSpeed;
  24. }
  25. }
  26. }

OnTriggerEnter()与OnTriggerStay()

1.触发条件

  • 双方必须有一方设置Is Trigger为Enable。
  • 双方必须有一方设置有Rigidbody刚体组件。

2.代码调试 

  1. private void OnTriggerEnter(Collider other)
  2. {
  3. Debug.Log(message:other.name);//获取gameobject的名字
  4. other.transform.position+= new Vector3(0, 0.44f, 0);//gameobject的y坐标发生变化。
  5. }

3.触发分主动与被动

  1. OnTriggerEnter(Collider other)与OntriggerStay(Collider other)的形参为被动的gameobject。
  2. 假设:ObjectA为设置为Is Trigger的一方,
  3. ObjectB为接触的另一方。
  4. 情况1:当ObjectA主动接触ObjectB,形参other为ObjectB.
  5. 情况2:当ObjectB主动接触ObjectA,形参other为ObjectA。

Play On Awake:实例化后自动播放

子弹碰撞检测

创建Shell脚本,用于炮弹的碰撞事件

脚本挂载在Shell预制体上

Shell预制体的 Capsule Collider 属性的 Is Trigger 设置为开启状态,这样会与其它网格发生碰撞(碰撞后如不发生事件则直接穿透)

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class Shell : MonoBehaviour
  5. {
  6. public GameObject ShellExplosionPrefab; //子弹爆炸效果的预制体
  7. // 脚本写完后,把做好的ShellExplosion预制体,挂在Shell预制体Shell脚本的ShellExplosionPrefab中
  8. // Start is called before the first frame update
  9. void Start()
  10. {
  11. }
  12. // Update is called once per frame
  13. void Update()
  14. {
  15. }
  16. // 子弹发生碰撞时效果
  17. private void OnTriggerEnter(Collider other)
  18. {
  19. // 实例化爆炸效果,当前位置,当前方向
  20. GameObject.Instantiate(ShellExplosionPrefab, transform.position, transform.rotation);
  21. // 把自身销毁
  22. GameObject.Destroy(this.gameObject);
  23. }
  24. }

爆炸效果完成后删除

创建脚本DestroyForTime,挂在预制体ShellExplosion上

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class DestroyForTime : MonoBehaviour
  5. {
  6. public float time = 1.5f; // 生存时间(设置动画时长)
  7. // Start is called before the first frame update
  8. void Start()
  9. {
  10. Destroy(this.gameObject, time); //预制体被实例化后,在time时间长度后销毁自身
  11. }
  12. // Update is called once per frame
  13. void Update()
  14. {
  15. }
  16. }

控制炮弹对坦克的伤害

先新增一个Tag:Tank,然后给Tank对象添加Tag属性为Tank,这样当炸弹碰撞的物体Tag属性是Tank时就是遇坦克发生碰撞,然后修改相关的属性等

Shell脚本修改为:

  1. public class Shell : MonoBehaviour
  2. {
  3. public GameObject ShellExplosionPrefab; //子弹爆炸效果的预制体
  4. // Start is called before the first frame update
  5. void Start()
  6. {
  7. }
  8. // Update is called once per frame
  9. void Update()
  10. {
  11. }
  12. // 子弹发生碰撞时效果
  13. private void OnTriggerEnter(Collider other)
  14. {
  15. // 实例化爆炸效果,当前位置,当前方向
  16. GameObject.Instantiate(ShellExplosionPrefab, transform.position, transform.rotation);
  17. // 把自身销毁
  18. GameObject.Destroy(this.gameObject);
  19. // 子弹碰撞的物体tag为Tank,说明是坦克
  20. if (other.gameObject.CompareTag("Tank"))
  21. {
  22. other.gameObject.SendMessage("TankDamage"); // 调用碰撞到的对象的TankDamage()方法
  23. }
  24. }
  25. }

新增一个TankHealth脚本,为坦克血量,挂载在坦克预制体上,所有坦克都是相同的血量属性

  1. public class TankHealth : MonoBehaviour
  2. {
  3. public int hp = 100; //坦克血量
  4. public GameObject tankExplosion; //坦克阵亡效果
  5. // Start is called before the first frame update
  6. void Start()
  7. {
  8. }
  9. // Update is called once per frame
  10. void Update()
  11. {
  12. }
  13. // 坦克受到伤害
  14. void TankDamage()
  15. {
  16. if (hp <= 0) return; // 已阵亡
  17. hp -= Random.Range(5, 15); //每次受到伤害损失5~15一个随机的伤害
  18. if (hp <= 0)
  19. {
  20. // 受到伤害后阵亡,播放坦克阵亡动画 TankExplosion
  21. // TankExplosion 的 Play On Awake 勾选上,被实例化后自动播放
  22. GameObject.Instantiate(tankExplosion, transform.position + Vector3.up, transform.rotation); // 为了效果,爆炸动画向上移动1米 + Vector3.up
  23. GameObject.Destroy(this.gameObject); // 销毁掉坦克自身
  24. }
  25. }
  26. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/116432
推荐阅读
相关标签
  

闽ICP备14008679号