1.检测目标物体与本物体的角度
//先获取到要检测的目标物体
GameObject mubiao = GameObject.Find("mubiao");
//获取起始物体和目标物体之间的向量
Vector3 v = mubiao.transform.position - start.transform.position;
//.normalized代表将向量变为标桩向量,这一步是获得两个物体之间的夹角的余玄值(cos)
float cos = Vector3.Dot(start.transform.forward, v.normalized);
//将这个cos转换为角度
float horm = Mathf.Acos(cos) * Mathf.Rad2Deg;
Debug.Log(horm);
2.检测物体在玩家的哪一侧
//先获取到要检测的目标物体
GameObject mubiao = GameObject.Find("mubiao");
//获取起始物体和目标物体之间的向量
Vector3 v = mubiao.transform.position - start.transform.position;
//.normalized代表将向量变为标准向量,返回的是两个向量的长度相乘,再乘以两个向量夹角的正弦 值(sin)
//相当于获得他们的法向量
Vector3 sin = Vector3.Cross(start.transform.forward, v.normalized);
//如果sin的y大于0说明在右边,小于0在左边,等于0说明在前后
if (sin.y > 0)
{
Debug.Log("右边");
}else if (sin.y < 0)
{
Debug.Log("左边");
}
else
{
Debug.Log("在前面或者后面");
}
3.让玩家看向某个物体
//利用Quaternion.LookRotation()这个API达到看向目标,并且进行旋转的效果
//先获取向量的差
Vector3 q1 = enemy.position - player.transform.position;
//进行旋转
player.transform.rotation = Quaternion.Lerp(player.transform.rotation, Quaternion.LookRotation(q1, Vector3.up), 0.1f);
4.用鼠标控制玩家旋转
public GameObject player;
//先定义一个数,检测鼠标的x值
public float mouseX;
//控制速度
public float speed;
void Update()
{
//得到鼠标的x值
mouseX = Input.GetAxis("Mouse X");
//让物体绕着y轴旋转,旋转的角度是鼠标的x的值乘以速度
Quaternion q = Quaternion.AngleAxis(mouseX * speed, Vector3.up);
//这里的*是被重载了的,这里的意思是两个四位数的角度相加
player.transform.rotation *= q ;
}
5.用四元数实现物体旋转
//先获取由圆心指向旋转物体的向量
Vector3 dir = enemy.transform.position - player.transform.position;
//每一帧所旋转的角度
Quaternion revolue = Quaternion.AngleAxis(angix, Vector3.up);
//每一帧旋转的物体所该到达的位置
Vector3 pos = revolue * dir;
//将pos的值赋值给游戏物体
enemy.transform.position = pos+player.transform.position;
6.游戏物体的一些基本控制
public class Game01Move : MonoBehaviour
{
//获取一个飞机
public GameObject player;
//控制飞机前进的速度
public float speed_z;
//控制飞机旋转的速度
public float speed_x;
//控制飞机倾斜的角度
public float speed_y;
void Update()
{
//接收输入的前进
float move_z = Input.GetAxis("Vertical");
//控制飞机进行移动
player.transform.Translate(new Vector3(0, 0, move_z*speed_z));
//接收旋转的方向
float move_x = Input.GetAxis("Horizontal");
player.transform.rotation *= Quaternion.AngleAxis(move_x*speed_x, Vector3.up);
//控制飞机倾斜角
if (Input.GetKey(KeyCode.Q))
{
player.transform.rotation *= Quaternion.AngleAxis(speed_y, Vector3.forward);
}
if (Input.GetKey(KeyCode.E))
{
player.transform.rotation *= Quaternion.AngleAxis(-speed_y, Vector3.forward);
}
}
}
7.相机跟随游戏物体
public class Game02CameraFollow : MonoBehaviour
{
//跟随的游戏物体
public GameObject player;
//与跟随物体的z轴的距离(相机离游戏物体的距离)
public float forward;
//与跟随物体的y的距离(相机的高度)
public float height;
//跟随物体的速度
public float speed;
//摄像机跟随
private void LateUpdate()
{
//相机的左右轴跟随游戏物体保持一至就行,不用进行更改
//这一句相当于使让相机保持一定的距离和游戏的物体
Vector3 v = -(player.transform.forward * forward) + new Vector3(0, height, 0);
//相机的具体位置
Vector3 pos = v + player.transform.position;
//将相机的具体的位置赋值给相机,并且用差值运算达到平滑的效果
transform.position = Vector3.Lerp(transform.position, pos, speed);
//使得相机看游戏物体
transform.LookAt(player.transform);
}
}
8.利用缓冲池实现子弹的循环利用
缓冲池类EnemyPool
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//这是一个缓冲池的类
public class EnemyPool : MonoBehaviour
{
//使用static关键字可以在其他类通过类名.方法的方式来访问该内容
public static EnemyPool Instance;
//调用这个类的时候就运行一次
private void Awake()
{
//相当于对这个声明的方法进行赋值,告诉别人调用的本类的这个方法
Instance = this;
}
//声明一个存放子弹的池子
GameObject bulletPool ;
//存放子弹的方法
public GameObject GetBulletPool()
{
//先判断是否有存放子弹的池子
if (bulletPool == null)
//如果没有就查询全局找到EnemyBulletPool并且赋值给bulletPool
bulletPool = GameObject.Find("EnemyBulletPool");
//返回bulletPool
return bulletPool;
}
public void Start()
{
}
}
子弹类Game03Bullet
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//public class Game03Bullet : MonoBehaviour
public class Game03Bullet : EnemyPool
{
public GameObject bullet;
public float speed;
//声明一个存放子弹的池子
private GameObject pool;
//计时
private float timer;
private void Start()
{
//调用EnemyPool类里面的方法得到缓冲池
pool = EnemyPool.Instance.GetBulletPool();
//pool = GameObject.Find("EnemyBulletPool");
}
void Update()
{
//计时
timer += Time.deltaTime;
if(timer > 5)
{
//如果时间大于5s就将子弹的父物体设置为缓冲池
transform.parent = pool.transform;
//并且把时间重新归0
timer = 0;
//这一步就相当于5s后子弹消失
gameObject.SetActive(false);
}
//子弹向前发射,相对于世界坐标系
bullet.transform.Translate(Vector3.forward*speed);
}
}
生成子弹类Enemy02LoadBullet
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy02LoadBullet : EnemyPool
{
private GameObject bullet;
private float timer = 0;
public GameObject place;
void Start()
{
//进行初始化,bullet在Resource文件夹找到bullet
bullet = Resources.Load<GameObject>("bullet");
}
// Update is called once per frame
void Update()
{
//计时
timer += Time.deltaTime;
if(timer > 3)
{
for(int i = 0; i < 9; i++)
{
GameObject bulletChild = null;
//初始化
GameObject pool = EnemyPool.Instance.GetBulletPool();
//判断池子里是否有东西
if(pool.transform.childCount > 0)
{
//如果有,子弹就是缓冲池的第一个物体
bulletChild = pool.transform.GetChild(0).gameObject;
//并且将子弹设的父类设置为null,下一次5s过后重新进入缓冲池,并且设置为显示
bulletChild.transform.parent = null;
bulletChild.SetActive(true);
}
else
{
//如果没有东西,就生成子弹
bulletChild = Instantiate(bullet);
}
bulletChild.transform.position = place.transform.position;
bulletChild.transform.rotation = place.transform.rotation * Quaternion.AngleAxis(-60+15 * i, Vector3.up);
timer = 0;
}
}
}
}
9.背景的移动拼接
void Update()
{
//如果背景到达-80的位置就执行
if (transform.position.z < -80)
{
//背景的拼接
transform.position += new Vector3(0, 0, 160);
}
//背景的移动
transform.Translate(Vector3.back * 0.3f, Space.Self);
}
10.拖拽UI图片
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class TestDraw : MonoBehaviour,IBeginDragHandler,IEndDragHandler,IDragHandler
{
//PointerEventData是Unity从设备硬件接收到的数据和事件相关的一些数据
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("Begin");
}
//拖拽中会连续回调
public void OnDrag(PointerEventData eventData)
{
Vector2 localPos;
//拖拽的实现
RectTransformUtility.ScreenPointToLocalPointInRectangle(
transform.parent as RectTransform, //获取Canvas的Transform
eventData.position, // 屏幕坐标系下触摸的点
eventData.pressEventCamera,//触发事件的相机
out localPos//获得本地坐标系的点
);
//修改位置
transform.localPosition = localPos;
Debug.Log("Drag");
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("End");
}
}