unity 敌人
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AI : MonoBehaviour
{undefined
public GameObject player;
public float attackrange;
public float movespeed;
// Start is called before the first frame update
// Update is called once per frame
void FixedUpdate()
{undefined
float dist = Vector3.Distance(player.transform.position, transform.position);
if (dist > attackrange)
{undefined
transform.Translate(Vector3.right * movespeed * Time.deltaTime);
}
Vector2 direction = player.transform.position - transform.position;
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
}
}
————————————————
版权声明:本文为CSDN博主「可没就是说」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_36190719/article/details/112884287
跟踪方式
宠物跟踪,检测到玩家离开一定范围后跟踪
玩家代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float h = Input.GetAxis ("Horizontal");
float v = Input.GetAxis ("Vertical");
if(h!=0 || v!=0){
transform.LookAt (transform.position+new Vector3(h,0,v));
transform.Translate (transform.forward*Time.deltaTime*5f,Space.World);
}
}
}
宠物移动代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PetMove : MonoBehaviour {
public Transform player;//主角
public float speed=1f;//移动的阻尼,值越小,移动越平缓
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {//如果主角和宠物直接的距离大于5,控制宠物跟随主角移动
if(Vector3.Distance(player.position,transform.position)>5f){
PetSmothFlow ();
//to do。。播放移动动画
}
//to do。。播放站立动画
//控制宠物的朝向
transform.LookAt (player.position);
}
//控制宠物的位置平滑移动
void PetSmothFlow(){
transform.position=Vector3.Lerp (transform.position,player.position,Time.deltaTime*speed);
}
}
raycast射线扇形检测
//
// LookDecision
//
//放射线检测
private bool Look(StateController controller)
{
var defaultStats = controller.defaultStats;
//一条向前的射线
if (LookAround(controller, Quaternion.identity, Color.green))
return true;
//多一个精确度就多两条对称的射线,每条射线夹角是总角度除与精度
float subAngle = (defaultStats.lookAngle / 2) / defaultStats.lookAccurate;
for (int i = 0; i < defaultStats.lookAccurate; i++)
{
if (LookAround(controller, Quaternion.Euler(0, -1 * subAngle * (i + 1), 0), Color.green)
|| LookAround(controller, Quaternion.Euler(0, subAngle * (i + 1), 0), Color.green))
return true;
}
return false;
}
//射出射线检测是否有Player
static public bool LookAround(StateController controller, Quaternion eulerAnger,Color DebugColor)
{
Debug.DrawRay(controller.eyes.position, eulerAnger * controller.eyes.forward.normalized * controller.defaultStats.lookRange, DebugColor);
RaycastHit hit;
if (Physics.Raycast(controller.eyes.position, eulerAnger * controller.eyes.forward, out hit, controller.defaultStats.lookRange) && hit.collider.CompareTag("Player"))
{
controller.chaseTarget = hit.transform;
return true;
}
return false;
}
自己的扇形检测
public class Tracking : MonoBehaviour
{
//
// LookDecision
//
[Range(0, 360)]
public float angle = 90f; //检测前方角度范围
[Range(0, 100)]
public float distance = 25f; //检测距离
public float rotatePerSecond = 90f; //每秒旋转角度
public int LayerMask = 3; //不发生碰撞的层
bool detected = false;
int LM;
void Start()
{
LM = ~(1 << LayerMask);
}
// Update is called once per frame
void Update()
{
if (GM.isActive)
{
if (detected)
{
//tracking
}
else
{
//detection
Vector3 tmp = new Vector3(0, 0, -angle / 2 + Mathf.Repeat(rotatePerSecond * Time.time, angle));
Quaternion Angel = Quaternion.Euler(tmp);
Vector3 tmp2 = Angel * new Vector3(0,1,0);
RaycastHit2D hit = Physics2D.Raycast(transform.position, tmp2, 120f, LM);
Debug.DrawRay(transform.position, tmp2, Color.red);
if (hit.collider == null)
{
Debug.Log("Angel.y: "+Angel.y);
Debug.Log("vector: " + tmp2);
}
else if (hit.collider.gameObject.CompareTag("Player"))
{
//检测到
Debug.Log("Find player");
detected = true;
GM.isActive = false;
}
else
{
}
}
}
}
}
怪物巡逻
public class Enemy : MonoBehaviour
{
// Start is called before the first frame update
public float enemy_speed = 11f;
public float attack_dis = 3f;
public float x1, y1, x2, y2;
public int direction = 0;
float t = 0.0f;
public GameObject player;
void Start()
{
}
// Update is called once per frame
void Update()
{
if (GM.isActive)
{
float dis = Vector2.Distance(player.transform.position, transform.position);
if(dis < attack_dis)
{
direction = -1;
transform.position = Vector2.MoveTowards(transform.position, player.transform.position,enemy_speed*Time.deltaTime);
}
else
{
if(direction == 0)
{
transform.position = new Vector2(Mathf.Lerp(x1, x2, t), y1);
t += 0.5f * Time.deltaTime;
if(t > 1.0f)
{
Debug.Log("direction change 0 to 1");
t = 0.0f;
direction = 1;
}
}
if (direction == 1)
{
transform.position = new Vector2(x2,Mathf.Lerp(y1, y2, t));
t += 0.5f * Time.deltaTime;
if (t > 1.0f)
{
Debug.Log("direction change 1 to 2");
t = 0.0f;
direction = 2;
}
}
if (direction == 2)
{
transform.position = new Vector2(Mathf.Lerp(x2, x1, t), y2);
t += 0.5f * Time.deltaTime;
if (t > 1.0f)
{
Debug.Log("direction change 2 to 3");
t = 0.0f;
direction = 3;
}
}
if (direction == 3)
{
transform.position = new Vector2(x1, Mathf.Lerp(y2, y1, t));
t += 0.5f*Time.deltaTime;
if (t > 1.0f)
{
t = 0.0f;
direction = 0;
}
}
}
}
}
}
血条
public class UI : MonoBehaviour
{
public Text score;
public GameObject gameover;
public Slider HPSlider;
public static int HP = 100;
// Start is called before the first frame update
void Start()
{
HPSlider.value = HPSlider.maxValue = HP;
}
// Update is called once per frame
void Update()
{
score.text = "score: " + GM.score;
if (HP>=0)
{
HPSlider.value = HP;
}
if (HP < 0)
{
GM.isActive = false;
}
if (!GM.isActive)
{
gameover.SetActive(true);
}
}
public static void Atack(int damage)
{
HP -= damage;
}
}
血条






浙公网安备 33010602011771号