AI 人工智能 探索 (三)
三类子弹的设计
using UnityEngine; using System.Collections; public class AI : AssembleModel { private Hashtable table; private Transform target; void Start() { table = new Hashtable(); target = Spawner("Target");//单个创建 } void Update() { //方向 Vector3 mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.y); Vector3 worldPos = Camera.main.ScreenToWorldPoint(mousePos); iTween.LookUpdate(gameObject, iTween.Hash("looktarget", worldPos, "time", 2, "axis", "y")); //瞄准图 RaycastHit hit = new RaycastHit(); Ray cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(cameraRay.origin, cameraRay.direction, out hit, 100)) { target.position = hit.point; } //fire:开火 if (Input.GetMouseButtonDown(0)) { // Transform transforms = Spawner("Capsule");//炮弹 // transforms.GetComponent<Bom>().OnPosition(this.transform, target); // Transform transforms = Spawner("bullet");//子弹 // transforms.GetComponent<Emission>().OnPosition(this.transform); Transform transforms = Spawner("daodan");//导弹 transforms.GetComponent<Missile>().OnPosition(this.transform, target); } } //离开碰撞 void OnTriggerExit(Collider other) { //如果消失 if (other.transform.name == otherName) { touch = false; otherName = ""; } table.Remove(other.transform.name); StartCoroutine(Independent(0.1f)); } //多物体碰撞 ,当移除后,必须检测已有碰撞中是否还有符合条件的 IEnumerator Independent(float i) { if (touch == false) //没碰 { foreach (DictionaryEntry de in table) { //检测碰撞,发现导入方法 //加入 Transform transform = de.Value as Transform; if (OnDetection(transform)) { otherName = transform.name; touch = true; } } } yield return new WaitForSeconds(i);//n秒执行一次 遍历,提高效率 } private bool touch = false;//和目标物体发生碰撞没有 private string otherName;//目标物体 //进入碰撞 void OnTriggerEnter(Collider other) { table.Add(other.transform.name, other.transform); if (this.transform.GetComponent<Attribute>().att == 2) { //测试用 print(other.transform.name); print(table.Count); } if (touch == false) //没碰 { foreach (DictionaryEntry de in table) { //检测碰撞,发现导入方法 //加入 Transform transform = de.Value as Transform; if (OnDetection(transform)) { otherName = other.transform.name; touch = true; } } } } //检测碰撞 bool OnDetection(Transform tr) { if (tr.name != transform.name)//碰点不是自己 { //这里写方法判断逻辑 if (tr.GetComponent<Attribute>().att != this.transform.GetComponent<Attribute>().att)//不同属性对打,相同属性 不打 { return true; } else {//重新选择敌人 return false; } } return false; } //逗留碰撞 void OnTriggerStay(Collider other) { if (other.transform.name == otherName) { //检测距离 float distance = Vector3.Distance(this.transform.position, other.transform.position);//距离公式 //根据距离 发射子弹, if (this.transform.name == "momo(Clone)001")//测试用 { this.transform.LookAt(other.transform); // print(this.transform.name + "发射" + otherName);//发射等通知 或 发射不等 } } } }
using UnityEngine; using System.Collections; //子弹轨迹 public class Emission : MonoBehaviour { // Use this for initialization void Start () { } private Transform transforms; public void OnPosition(Transform vec) { transforms = vec; this.transform.position = new Vector3(transforms.position.x, 1.5f, transforms.position.z); this.transform.rotation = transforms.rotation; this.transform.rigidbody.velocity = transforms.TransformDirection(Vector3.forward * 10); } void Update () { } }
using UnityEngine; using System.Collections; //导弹 public class Missile : AssembleModel { public void OnPosition(Transform transforms, Transform target) { missileSpeed = 31f;//子弹速度 missileRotateSpeed = 2f;//子弹方向 missile = transforms; man = target; if (man != null && missile != null) { float manWidth = man.GetComponent<MeshFilter>().mesh.bounds.size.x * man.localScale.x; float missileLength = missile.GetComponent<MeshFilter>().mesh.bounds.size.z * missile.localScale.z; collisionDistance = manWidth / 2 + missileLength / 2; transform.position = transforms.position; } } private Transform man; private Transform missile; private float missileSpeed; private float missileRotateSpeed; bool whehterShooted = false; float distance; float collisionDistance; // Update is called once per frame void Update() { if (missile != null) { distance = Vector3.Distance(this.transform.position, man.position); ////导弹朝向人 法一 // transform.LookAt(man.transform); //导弹朝向人 法二 Quaternion missileRotation = Quaternion.LookRotation(man.transform.position - transform.position, Vector3.up); transform.rotation = Quaternion.Slerp(transform.rotation, missileRotation, Time.deltaTime * missileRotateSpeed); transform.rotation = missileRotation; //导弹朝向人 法三 //Vector3 targetDirection = man.transform.position - missile.transform.position; //float angle = Vector3.Angle(targetDirection,missile.transform.forward);//取得两个向量间的夹角 //print("angle:"+angle.ToString()); //if (angle > 5) //{ // missile.transform.Rotate(Vector3.up, angle); //} transform.Translate(Vector3.forward * Time.deltaTime * missileSpeed); //检测是否发生碰撞。这里通过两者的distance来判断 if (distance <= collisionDistance) { Despawn(transform); } } } }
using UnityEngine; using System.Collections; //炮弹轨迹 public class Bom : AssembleModel { public float speed = 10; private float distanceToTarget; private bool move = true; void Start() { } private Vector3 thisVector;//本地坐标 private Vector3 otherVector;//目标坐标 private Transform transforms1; private Transform target1; public void OnPosition(Transform transforms, Transform target) { transforms1 = transforms; target1 = target; thisVector = transforms.position; otherVector = target.position; distanceToTarget = Vector3.Distance(thisVector, otherVector); Vector3 ve = new Vector3(); ve = thisVector; ve.y += 1; this.transform.position = ve; StartCoroutine(Shoot()); } IEnumerator Shoot() { move = true;//因为是协成,会导致 异步改变 while (move) { Vector3 targetPos = otherVector; this.transform.LookAt(targetPos); float angle = Mathf.Min(1, Vector3.Distance(transforms1.position, target1.position) / distanceToTarget) * 45; this.transform.rotation = this.transform.rotation * Quaternion.Euler(Mathf.Clamp(-angle, -42, 42), 0, 0); float currentDist = Vector3.Distance(this.transform.position, otherVector); // print("currentDist" + currentDist + "=="+targetPos); if (currentDist < 0.5f) { move = false; CleanUp(); } else { this.transform.Translate(Vector3.forward * Mathf.Min(speed * Time.deltaTime, currentDist)); } yield return null; } } void CleanUp() { Despawn(this.transform);//单个删除 } }