Unity入门4——重要组件与API

news2024/12/25 9:10:25

一、GameObject

(一)成员变量

// 名字                                                    
print(this.gameObject.name);                            
this.gameObject.name = "Lesson4唐老狮改名";                  
print(this.gameObject.name);           

// 是否激活                                                  
print(this.gameObject.activeSelf);    

// 是否是静态                                                 
print(this.gameObject.isStatic);    

// 层级                                                    
print(this.gameObject.layer);     

// 标签                                                    
print(this.gameObject.tag);          

// transform                                             
// this.transform 上一节课讲解的 通过Mono去得到的依附对象的GameObject的位置信息 
// 他们得到的信息是一样 都是依附的GameObject的位置信息                       
print(this.gameObject.transform.position); 

 

(二)静态方法

  1. 创建自带几何体

    只要得到了一个 GameObject 对象,就可以得到它身上挂在的任何脚本信息通过 obj.GetComponent 来获得

  2. 查找对象 

 

两种找单个对象的共同点:                                                           

 -   无法找到失活的对象的,只能找到激活的对象                                                             
 -   如果场景中存在多个满足条件的对象,我们无法准确确定找到的是谁 

 

// 1.查找单个对象                                                                
// 通过对象名查找                                                                
// 这个查找效率比较低下  因为他会在场景中的所有对象去查找                                           
// 没有找到 就会返回null                                                          
GameObject obj2 = GameObject.Find("唐老狮");                                
if( obj2 != null ) print(obj2.name);                                                      
else print("没有找到对应对象"); 

// 通过tag来查找对象                                                             
// GameObject obj3 = GameObject.FindWithTag("Player");                    
// 该方法和上面这个方法 效果一样 只是名字不一样而已                                              
GameObject obj3 = GameObject.FindGameObjectWithTag("Player");            
if (obj3 != null) print("根据tag找的对象" + obj3.name);                                                             
else print("根据tag没有找到对应对象");                                                                    
                                                                         
// 得到某一个单个对象 目前有2种方式                                                     
// 1.是public从外部面板拖 进行关联                                                   
// 2.通过API去找                                                              
                                                                         
// 2查找多个对象                                                                
// 找多个对象的API 只能是通过tag去找多个 通过名字 是没有找多个的方法的

// 通过tag找到多个对象                                                            
// 它也是 只能找到 激活对象 无法找到失活对象                                                 
GameObject[] objs = GameObject.FindGameObjectsWithTag("Player");         
print("找到tag为Player对象的个数" + objs.Length);                                
                                                                         
// 还有几个查找对象相关是用的比较少的方法 是GameObject父类 Object提供的方法                          
// 引出额外知识点 Unity中的Object和C#中的万物之父的区别                                      
// Unity里面的Object 不是指的万物之父object                                          
// Unity里的Object 命名空间在UnityEngine中的 Object类 也是集成万物之父的一个自定义类               
// C#中的Object 命名空间是在System中的                                              
                                                                         
// 它可以找到场景中挂载的某一个脚本对象                                                     
// 效率更低 上面的GameObject.Find 和通过FindWithTag找 只是遍历对象                         
// 这个方法 不仅要遍历对象 还要遍历对象上挂载的脚本                                              
Lesson4 o = GameObject.FindObjectOfType<Lesson4>();                      
print(o.gameObject.name);

 

3.创建对象

 // 实例化对象(克隆对象)的方法                                                         
// 实例化(克隆)对象 它的作用 是根据一个GameObject对象 创建出一个和它一模一样的对象                        
GameObject obj5 = GameObject.Instantiate(myObj);                         
// 以后学了更多知识点 就可以在这操作obj5                                                  
// 如果你继承了 MonoBehavior 其实可以不用写GameObject一样可以使用                            
// 因为 这个方法时Unity里面的 Object基类提供给我们的 所以可以直接用                                
// Instantiate(myObj);

 

4.删除对象

 // 删除对象的方法                                                                
GameObject.Destroy(myObj2);                                              
// 第二个参数 代表延迟几秒钟删除                                                        
GameObject.Destroy(obj5, 5);                                             
// Destroy不仅可以删除对象 还可以删除脚本                                                
// GameObject.Destroy(this);                                              
                                                                         
// 删除对象有两种作用                                                              
// 1.是删除指定的一个游戏对象                                                         
// 2.是删除一个指定的脚本对象                                                         
// 注意:这个Destroy方法 不会马上移除对象 只是给这个对象加了一个移除标识                                
//      一般情况下 它会在下一帧时把这个对象移除并从内存中移除                                       
                                                                         
// 如果没有特殊需求 就是一定要马上移除一个对象的话                                               
// 建议使用上面的 Destroy方法 因为 是异步的 降低卡顿的几率                                      
// 下面这个方法 就是立即把对象 从内存中移除了                                                 
// GameObject.DestroyImmediate(myObj);                                    
                                                                         
// 如果是继承MonoBehavior的类 不用写GameObject                                      
// Destroy(myObj2);                                                       
// DestroyImmediate(myObj);

 5.过场景不移除

// 过场景不移除                                                                 
// 默认情况 在切换场景时 场景中对象都会被自动删除掉                                              
// 如果你希望某个对象 过场景不被移除                                                      
// 下面这句代码 就是不想谁过场景被移除 就传谁                                                 
// 一般都是传 依附的GameObject对象                                                  
// 比如下面这句代码的意思 就是自己依附的GameObject对象 过场景不被删除                                
GameObject.DontDestroyOnLoad(this.gameObject);                           
// 如果继承MOnoBehavior也可以直接写                                                 
// DontDestroyOnLoad(this.gameObject); 

 

(三)成员方法

1.创建空物体

// 创建空物体                                                                                         
// new一个GameObject就是在创建一个空物体                                                                     
GameObject obj6 = new GameObject();                                                             
GameObject obj7 = new GameObject("创建的空物体");                                                  
GameObject obj8 = new GameObject("顺便加脚本的空物体", typeof(Lesson2), typeof(Lesson1));   

2.添加脚本

// 为对象添加脚本                                                                                       
// 继承MOnoBehavior的脚本 是不能够去new                                                                    
// 如果想要动态的添加继承MonoBehavior的脚本 在某一个对象上                                                            
// 直接使用GameObject提供的方法即可                                                                         
Lesson1 les1 = obj6.AddComponent(typeof(Lesson1)) as Lesson1;                                   
// 用泛型更方便                                                                                        
Lesson2 les2 = obj6.AddComponent<Lesson2>();                                                    
// 通过返回值 可以得到加入的脚本信息                                                                             
// 来进行一些处理    

// 得到脚本的成员方 和继承Mono的类得到脚本的方法 一模一样

3.标签比较

// 标签比较                                                                                          
// 下面两种比较的方法 是一样的                                                                                
if(this.gameObject.CompareTag("Player")) print("对象的标签 是 Player");                                                                           
if(this.gameObject.tag == "Player") print("对象的标签 是 Player"); 

4.激活失活

// 设置激活失活                                                                                        
// false 失活                                                                                      
// true 激活                                                                                       
obj6.SetActive(false);                                                                          
obj7.SetActive(false);                                                                          
obj8.SetActive(false);

5.广播

次要的成员方法了解即可,不建议使用

下面讲的方法,都不建议大家使用,效率比较低

通过广播或者发送消息的形式,让自己或者别人执行某些行为方法

 

// 通知自己 执行什么行为                                                                                   
// 命令自己 去执行这个TestFun这个函数 会在自己身上挂在的所有脚本去找这个名字的函数                                                  
// 它会去找到 自己身上所有的脚本 有这个名字的函数去执行                                                                   
this.gameObject.SendMessage("TestFun");                                                         
this.gameObject.SendMessage("TestFun2", 199);                                                   
                                                                                                
// 广播行为 让自己和自己的子对象执行                                                                             
// this.gameObject.BroadcastMessage("函数名");                                                      
                                                                                                
// 向父对象和自己发送消息 并执行                                                                               
// this.gameObject.SendMessageUpwards("函数名");

二、Time

(一)时间缩放比例

// 时间停止 Time.timeScale = 0;

// 回复正常 Time.timeScale = 1;

// 2倍速 Time.timeScale = 2;

(二)帧间隔时间

// 帧间隔时间 主要是用来计算位移                                   
// 路程 = 时间*速度                                        
// 根据需求 选择参与计算的间隔时间                                  
// 如果希望 游戏暂停时就不动的 那就使用deltaTime                      
// 如果希望 不受暂停影响 unscaledDeltaTime                     
                                                    
// 帧间隔时间:最近的一帧 用了多长时间(秒)                             
// 受scale影响                                          
print("帧间隔时间" + Time.deltaTime);                  
// 不受scale影响的帧间隔时间                                   
print("不受scale影响的帧间隔时间" + Time.unscaledDeltaTime);

(三)游戏开始到现在的时间

// 它主要用来计时 单机游戏中计时                                     
// 受scale影响                                            
print("游戏开始到现在的时间:" + Time.time);                   
// 不受scale影响                                           
print("不受scale影响的游戏开始到现在的时间:" + Time.unscaledTime);

(四)物理帧间隔时间 FixedUpdate

private void FixedUpdate()                  
{                                                 
    // 受scale影响                              
    print(Time.fixedDeltaTime);           
    // 不受scale影响                             
    print(Time.fixedUnscaledDeltaTime);     
}       

(五)帧数

// 从开始到现在游戏跑了多少帧(次循环) print(Time.frameCount);

 Time 相关的内容
​ 最常用的就是

  1. 帧间隔时间,就用计算位移相关内容

  2. 时间缩放比例,用来暂停或者倍速等等

  3. 帧数(帧同步)

三、Transform

(一)Vector3

 // 常用                               
print(Vector3.zero);    //  0  0  0          
print(Vector3.right);   //  1  0  0         
print(Vector3.left);    // -1  0  0         
print(Vector3.forward); //  0  0  1       
print(Vector3.back);    //  0  0 -1         
print(Vector3.up);      //  0  1  0            
print(Vector3.down);    //  0 -1  0         
                                   
// 常用的一个方法                          
// 计算两个点之间的距离的方法                    
print(Vector3.Distance(v1, v2));  

 

(二)位置

// 相对世界坐标系                                                                                            
// this.gameObject.transform                                                                          
// 通过position得到的位置 是相对于 世界坐标系的 原点的位置                                                                  
// 可能和面板上显示的 是不一样的                                                                                    
// 因为如果对象有父子关系 并且父对象位置 不在原点 那么 和面板上肯定就是不一样的                                                           
print(this.transform.position);                                                                      
                                                                                                     
// 相对父对象                                                                                              
// 这两个坐标 对于我们来说 很重要 如果你想以面板坐标为准来进行位置设置                                                                
// 那一定是通过localPosition来进行设置的                                                                          
print(this.transform.localPosition);                                                                 
                                                                                                     
// 他们两个 可能出现是一样的情况                                                                                    
// 1.父对象的坐标 就是世界坐标系原点0,0,0                                                                            
// 2.对象没有父对象                                                                                          
                                                                                                     
// 注意:位置的赋值不能直接改变x,y,z 只能整体改变                                                                         
// 不能单独改 x y z某一个值                                                                                    
// this.transform.position.x = 10;                                                                    
this.transform.position = new Vector3(10, 10, 10);                                                   
this.transform.localPosition = Vector3.up * 10;                                                      
                                                                                                     
// 如果只想改一个值x y和z要保持原有坐标一致                                                                             
// 1.直接赋值                                                                                             
this.transform.position = new Vector3(19, this.transform.position.y, this.transform.position.z);     
// 2.先取出来 再赋值                                                                                         
// 虽然不能直接改 transform的 xyz 但是 Vector3是可以直接改 xyz的                                                       
// 所以可以先取出来改Vector3 再重新赋值                                                                             
Vector3 vPos = this.transform.localPosition;                                                         
vPos.x = 10;                                                                                         
this.transform.localPosition = vPos;                                                                 
                                                                                                     
// 如果你想得到对象当前的 一个朝向                                                                                   
// 那么就是通过 trnasform. 出来的                                                                               
// 对象当前的各朝向                                                                                           
// 对象当前的面朝向                                                                                           
print(this.transform.forward);                                                                       
// 对象当前的头顶朝向                                                                                          
print(this.transform.up);                                                                            
// 对象当前的右手边                                                                                           
print(this.transform.right);

 

(三)位移

// 理解坐标系下的位移计算公式
// 路程 = 方向 * 速度 * 时间

// 方式一 自己计算
// 想要变化的 就是 position

// 用当前的位置 + 我要动多长距离  得出最终所在的位置
// this.transform.position = this.transform.position + this.transform.up * 1 * Time.deltaTime;

// 因为我用的是 this.transform.forward 所以它始终会朝向相对于自己的面朝向去动
// this.transform.position += this.transform.forward * 1 * Time.deltaTime;

// 方向非常重要 因为 它决定了你的前进方向
// this.transform.position += Vector3.forward * 1 * Time.deltaTime;

// 方式二 API
// 参数一:表示位移多少  路程 = 方向 * 速度 * 时间
// 参数二:表示 相对坐标系   默认 该参数 是相对于自己坐标系的

// 1.相对于世界坐标系的 Z轴 动  始终是朝 世界坐标系 的 Z轴正方向移动
this.transform.Translate(Vector3.forward * 1 * Time.deltaTime, Space.World);

// 2.相对于世界坐标的 自己的面朝向去动   始终朝自己的面朝向移动
this.transform.Translate(this.transform.forward * 1 * Time.deltaTime, Space.World);

// 3.相对于自己的坐标系 下的 自己的面朝向向量移动 (一定不会这样让物体移动) XXXXXXX
// this.transform.Translate(this.transform.forward * 1 * Time.deltaTime, Space.Self);

// 4.相对于自己的坐标系 下的 Z轴正方向移动  始终朝自己的面朝向移动
this.transform.Translate(Vector3.forward * 1 * Time.deltaTime, Space.Self);

// 注意:一般使用API来进行位移



(四)欧拉角度

// 相对世界坐标角度
print(this.transform.eulerAngles);

// 相对父对象角度
print(this.transform.localEulerAngles);

// 注意:设置角度和设置位置一样 不能单独设置xyz 要一起设置
// 如果我们希望改变的 角度 是面板上显示的内容 那一点是改变 相对父对象的角度
// this.transform.localEulerAngles = new Vector3(10, 10, 10);
// this.transform.eulerAngles = new Vector3(10, 10, 10);
print(this.transform.localEulerAngles);
 

(五)欧拉旋转 

// 自己计算(省略不讲了 和位置一样 不停改变角度即可)

// API计算
// 自转
// 每个轴 具体转多少度
// 第一个参数 相当于 是旋转的角度 每一帧 
// 第二个参数 默认不填 就是相对于自己坐标系 进行的旋转
// this.transform.Rotate(new Vector3(0, 10, 0) * Time.deltaTime);
this.transform.Rotate(new Vector3(0, 10, 0) * Time.deltaTime, Space.World);

// 相对于某个轴 转多少度
// 参数一:是相对哪个轴进行转动
// 参数二:是转动的 角度 是多少
// 参数三:默认不填 就是相对于自己的坐标系 进行旋转
//        如果填  可以填写相对于 世界坐标系进行旋转
// this.transform.Rotate(Vector3.right, 10 * Time.deltaTime);
this.transform.Rotate(Vector3.right, 10 * Time.deltaTime, Space.World);

// 相对于某一个点转
// 参数一:相当于哪一个点 转圈圈
// 参数二:相对于那一个点的 哪一个轴转圈圈
// 参数三:转的度数  旋转速度 * 时间
this.transform.RotateAround(Vector3.zero, Vector3.right, 10 * Time.deltaTime);



(六)缩放与看向

// 相对世界坐标系
print(this.transform.lossyScale);
// 相对本地坐标系(父对象)
print(this.transform.localScale);

// 注意:
// 1.同样缩放不能只改xyz 只能一起改(相对于世界坐标系的缩放大小只能得 不能改)
// 所以 我们一般要修改缩放大小 都是改的 相对于父对象的 缩放大小 localScale
this.transform.localScale = new Vector3(3, 3, 3);

// 2.Unity没有提供关于缩放的API
// 之前的 旋转 位移 都提供了 对应的 API 但是 缩放并没有
// 如果你想要 让 缩放 发生变化 只能自己去写(自己算)
this.transform.localScale += Vector3.one * Time.deltaTime;           

// 让一个对象的面朝向 可以一直看向某一个点或者某一个对象            
// 看向一个点 相对于世界坐标系的                        
this.transform.LookAt(Vector3.zero);   
// 看向一个对象 就传入一个对象的  Transform信息           
this.transform.LookAt(lookAtObj);        



(七)父子关系

1.获取和设置父对象 


// 获取父对象
print(this.transform.parent.name);
// 设置父对象 断绝父子关系
this.transform.parent = null;
// 设置父对象 认爸爸
this.transform.parent = GameObject.Find("Father2").transform;

// 通过API来进行父子关系的设置
this.transform.SetParent(null);  // 断绝父子关系
this.transform.SetParent(GameObject.Find("Father2").transform);  // 认爸爸

// 参数一:我的父亲
// 参数二:是否保留世界坐标的 位置 角度 缩放 信息
//        true  会保留 世界坐标下的状态  和 父对象 进行计算 得到本地坐标系的信息
//        false 不会保留 会直接把世界坐标系下的 位置角度缩放 直接赋值到 本地坐标系下 
this.transform.SetParent(GameObject.Find("Father3").transform, false);


2.抛妻弃子


// 就是和自己的所有儿子 断绝关系 没有父子关系了
this.transform.DetachChildren();


3.获取子对象


// 按名字查找儿子
// 找到儿子的 transform信息
// Find方法 是能够找到 失活的对象的 !!!!! GameObject相关的 查找 是不能找到失活对象的
print(this.transform.Find("Cube (1)").name);
// 他只能找到自己的儿子 找不到自己的孙子 !!!!!!
print(this.transform.Find("GameObject").name);
// 虽然它的效率 比GameObject.Find相关 要高一些 但是 前提是你必须知道父亲是谁 才能找

// 遍历儿子
// 如何得到有多少个儿子
// 1.失活的儿子也会算数量
// 2.找不到孙子 所以孙子不会算数量
print(this.transform.childCount);

// 通过索引号 去得到自己对应的儿子
// 如果编号 超出了儿子数量的范围 那会直接报错的 
// 返回值 是 transform 可以得到对应儿子的 位置相关信息
this.transform.GetChild(0);

for (int i = 0; i < this.transform.childCount; i++) 
    print("儿子的名字:" + this.transform.GetChild(i).name);


4.儿子的操作


// 判断自己的爸爸是谁
// 一个对象 判断自己是不是另一个对象的儿子
if(son.IsChildOf(this.transform)) print("是我的儿子");

// 得到自己作为儿子的编号
print(son.GetSiblingIndex());
// 把自己设置为第一个儿子
son.SetAsFirstSibling();
// 把自己设置为最后一个儿子
son.SetAsLastSibling();
// 把自己设置为指定个儿子
// 就算你填的数量 超出了范围(负数或者更大的数) 不会报错 会直接设置成最后一个编号
son.SetSiblingIndex(1);


(八)坐标转换

1.世界坐标转本地坐标


// 世界坐标系转本地坐标系 可以帮助我们大概判断一个相对位置

// 世界坐标系的点 转换 为相对本地坐标系的点  
// 受到缩放影响
print("转换后的点 " + this.transform.InverseTransformPoint(Vector3.forward));

// 世界坐标系的方向 转换 为相对本地坐标系的方向 
// 不受缩放影响
print("转换后的方向" + this.transform.InverseTransformDirection(Vector3.forward));

// 受缩放影响
print("转换后的方向(受缩放影响)" + this.transform.InverseTransformVector(Vector3.forward));


2.本地坐标转世界坐标


// 本地坐标系的点 转换 为相对世界坐标系的点 受到缩放影响
print("本地转世界点" + this.transform.TransformPoint(Vector3.forward));

// 本地坐标系的方向 转换 为相对世界坐标系的方向 
// 不受缩放影响
print("本地转世界方向" + this.transform.TransformDirection(Vector3.forward));

// 受缩放影响
print("本地转世界方向(受缩放影响)" + this.transform.TransformVector(Vector3.forward));



四、Input


(一)鼠标在屏幕上的位置

// 屏幕坐标的原点 是在 屏幕的左下角  往右是X轴正方向 往上时Y轴正方向
// 返回值时Vector3 但是只有 x和y有值 z一直是0 是因为屏幕本来就是2D的 不存在Z轴
print(Input.mousePosition);


(二)检测鼠标输入

// 鼠标按下相关检测 对于我们来说
// 比如: 1.可以做 发射子弹
//       2.可以控制摄像机 转动

// 鼠标按下一瞬间 进入
// 0左键 1右键 2中键
// 只要按下的这一瞬间 进入一次
if(Input.GetMouseButtonDown(0)) print("鼠标左键按下了");

// 鼠标抬起一瞬间 进入
if(Input.GetMouseButtonUp(0)) print("鼠标左键抬起了");

// 鼠标长按按下抬起都会进入
// 就是 当按住按键不放时 会一直进入 这个判断
if(Input.GetMouseButton(1)) print("右键按下");

// 中键滚动
// 返回值的 y -1往下滚  0没有滚  1往上滚
// 它的返回值 是Vector的值 我们鼠标中键滚动 会改变其中的Y值
print(Input.mouseScrollDelta);
 

(三)检测键盘输入

 

// 比如说 按一个键释放一个技能或者切换武器 等等的操作

// 键盘按下
if(Input.GetKeyDown(KeyCode.W)) print("W键按下");

// 传入字符串的重载
// 这里传入的 字符串 不能是大写的 不然会报错
// 只能传入小写字符串
if(Input.GetKeyDown("q")) print("q按下");

// 键盘抬起
if(Input.GetKeyUp(KeyCode.W)) print("W键抬起");

// 键盘长按
if(Input.GetKey(KeyCode.W)) print("W键长按");



(四)检测默认轴输入

​ 在 Edit --> Project Setting --> Input Manager 中设置默认轴

image-20220419131417334

 

// 我们学习鼠标 键盘输入 主要是用来
// 控制玩家 比如 旋转 位移等等
// 所以Unity提供了 更方便的方法 来帮助我们控制 对象的 位移和旋转

// 键盘AD按下时 返回 -1到1之间的变换
// 相当于 得到得这个值 就是我们的 左右方向 我们可以通过它来控制 对象左右移动 或者左右旋转
float h = Input.GetAxis("Horizontal");

// 键盘SW按下时 返回 -1到1之间的变换
// 得到得这个值 就是我们的 上下方向 我们可以通过它来控制 对象上下移动 或者上下旋转
print(Input.GetAxis("Vertical"));

// 鼠标横向移动时 -1 到 1 左 右
print(Input.GetAxis("Mouse X"));

// 鼠标竖向移动时  -1 到 1 下 上
print(Input.GetAxis("Mouse Y"));

// 我们默认的 GetAxis方法 是有渐变的 会总 -1~0~1之间 渐变 会出现小数

// GetAxisRaw方法 和 GetAxis使用方式相同
// 只不过 它的返回值 只会是 -1 0 1 不会有中间值



(五)其他

// 是否有任意键或鼠标长按
if(Input.anyKey) print("有一个键长按");

// 是否有任意键或鼠标按下
if(Input.anyKeyDown)
{
    print("有一个键 按下");
    // 这一帧的键盘输入
    print(Input.inputString);
}

// 手柄输入相关
// 得到连接的手柄的所有按钮名字
string[] strs = Input.GetJoystickNames();

// 某一个手柄键按下
if(Input.GetButtonDown("Jump")) { }

// 某一个手柄键抬起
if (Input.GetButtonUp("Jump")) { }

// 某一个手柄键长按
if (Input.GetButton("Jump")) { }

// 移动设备触摸相关
if(Input.touchCount > 0)
{
    Touch t1 = Input.touches[0];
    // 位置
    print(t1.position);
    // 相对上次位置的变化
    print(t1.deltaPosition);
}

// 是否启用多点触控
Input.multiTouchEnabled = false;

// 陀螺仪(重力感应)
// 是否开启陀螺仪 必须开启 才能正常使用
Input.gyro.enabled = true;
// 重力加速度向量
print(Input.gyro.gravity);
// 旋转速度
print(Input.gyro.rotationRate);
// 陀螺仪 当前的旋转四元数 
// 比如 用这个角度信息 来控制 场景上的一个3D物体受到重力影响
// 手机怎么动 它怎么动
print(Input.gyro.attitude);



(六)示例

1.用 WASD 键控制坦克的前进后退,左右转向 


// Input.GetAxis("Horizontal"); 水平方向 -1到1之间的值 0就是没有按下
// Input.GetAxis("Vertical");  竖直方向 -1到1之间的值 0就是没有按下
// ws键 控制位移
// 公式: 前进方向 * 速度 * 时间 * 当前是否移动(-1~1 相当于 正向还是反向的感觉 不按就不动 0)
this.transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime * Input.GetAxis("Vertical"));

// ad键 控制 左右转向
// 公式: 转动的轴 * 速度 * 时间 * 当前是否移动(-1~1 相当于 正向还是反向的感觉 不按就不动 0)
this.transform.Rotate(Vector3.up * rotateSpeed * Time.deltaTime * Input.GetAxis("Horizontal"));


2.鼠标左右移动控制坦克的转向


// 鼠标输入相关 
// Input.GetAxis("Mouse X");
// 公式: 转动的轴 * 速度 * 时间 * 当前是否移动(-1~1 相当于 正向还是反向的感觉 不按就不动 0)
head.Rotate(Vector3.up * headRotateSpeed * Time.deltaTime * Input.GetAxis("Mouse X"));


3.鼠标滚轮控制炮管的抬起放下


// Input.mouseScrollDelta.y
pkPos.Rotate(Vector3.right * pkRotateSpeed * Time.deltaTime * Input.mouseScrollDelta.y);


五、Screen


(一)静态属性

常用


// 当前屏幕分辨率
Resolution r = Screen.currentResolution;
print("当前屏幕分辨率的宽" + r.width + "高" + r.height);

// 屏幕窗口当前宽高
// 这得到的 是当前 窗口的 宽高 不是设备分辨率的宽高
// 一般写代码 要用窗口宽高 做计算时 就用他们
print(Screen.width);
print(Screen.height);

// 屏幕休眠模式 
Screen.sleepTimeout = SleepTimeout.NeverSleep;


不常用


// 运行时是否全屏模式
Screen.fullScreen = true;

// 窗口模式
// 独占全屏   FullScreenMode.ExclusiveFullScreen
// 全屏窗口   FullScreenMode.FullScreenWindow
// 最大化窗口 FullScreenMode.MaximizedWindow
// 窗口模式   FullScreenMode.Windowed
Screen.fullScreenMode = FullScreenMode.Windowed;

// 移动设备屏幕转向相关
// 允许自动旋转为左横向 Home键在左
Screen.autorotateToLandscapeLeft = true;

// 允许自动旋转为右横向 Home键在右
Screen.autorotateToLandscapeRight = true;

// 允许自动旋转到纵向 Home键在下
Screen.autorotateToPortrait = true;

// 允许自动旋转到纵向倒着看 Home键在上
Screen.autorotateToPortraitUpsideDown = true;

// 指定屏幕显示方向
Screen.orientation = ScreenOrientation.Landscape;

 (二)静态方法

// 设置分辨率 一般移动设备不使用
Screen.SetResolution(1920, 1080, false);
sleepTimeout = SleepTimeout.NeverSleep;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/638367.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

手机号码应该如何选择呢?一文解决你的选择困难症!

哈喽大家好&#xff0c;我是搜卡之家葫芦弟。最近有一些小伙伴们私信葫芦弟&#xff0c;想办一个本地的手机号&#xff0c;想着长久一直使用的。既然是长久使用&#xff0c;那就想选一个不错的号码&#xff0c;手机靓号的话&#xff0c;好一点的号码价格又太贵。这不是要在平凡…

参与PK赢大奖!阿里云机器学习平台PAI助力开发者激发AIGC潜能

近年来&#xff0c;随着海量多模态数据在互联网的爆炸性增长和训练深度学习大模型的算力大幅提升&#xff0c;AI生成内容&#xff08;AI Generated Content&#xff0c;AIGC&#xff09;的应用呈现出爆发性增长趋势。为助力开发者能够一站式快速搭建文生图、对话等热门场景应用…

GPT问题摘录go中接口实现和继承

go如何实现接口 package mainimport "fmt"type Shape interface {Area() float64 }type Circle struct {Radius float64 }func (c Circle) Area() float64 {return 3.14 * c.Radius * c.Radius }func main() {c : Circle{Radius: 6.2}fmt.Println(c.Area()) } 首先我…

在线合并Excel文档的HTML网页工具

构建一个在线合并Excel文档的HTML网页工具 导语&#xff1a; 在本篇技术分享文章中&#xff0c;我将向您展示如何使用HTML、CSS和JavaScript构建一个功能强大的在线合并Excel文档的网页工具。这个工具可以帮助用户将多个Excel文件合并成一个文件&#xff0c;提高工作效率和方便…

GDT陶瓷气体放电管会不会烧坏?有没有方向?

首先第一个问题&#xff1a;GDT陶瓷气体放电管会不会烧坏&#xff1f;标准答案&#xff1a;会的。 GDT放电管是一种过压保护开关型元件&#xff0c;通常用在电路防护的前端&#xff0c;起泄放浪涌电流及脉冲过电压防护的效果&#xff0c;在遇到电路设计规划不合理以及选型不当时…

汇川H5U计数器轴编程应用(高速计数和测速应用)

H5U编码器轴和脉冲轴相关应用测试请参看下面文章: H5U PLC本地脉冲轴和本地编码器轴测试_RXXW_Dor的博客-CSDN博客H5U PLC如何通过EtherCAT总线控制伺服运动,请参看下面的博客汇川H5U PLC通过EtherCAT总线控制SV660N和X3E伺服_RXXW_Dor的博客-CSDN博客。https://blog.csdn.n…

IDEA安装教程2023

在本文中&#xff0c;我们将提供关于如何安装 IntelliJ IDEA 的详细步骤。如果您是初学者或只是想尝试一下 IDEA&#xff0c;我们建议您下载 Community 版。如果您需要更多高级功能&#xff0c;可以选择 Ultimate 版。 步骤一&#xff1a;下载 IntelliJ IDEA 首先&#xff0c;…

潮向新世界丨2023亚马逊云科技出海日精彩回顾

2023年6月9日&#xff0c;2023亚马逊云科技“潮向新世界”出海日活动在深圳及线上同步盛大开启。在这场出海盛会中&#xff0c;亚马逊云科技、中国出海企业代表和合作伙伴们分享了哪些精彩内容&#xff1f;他们又对中国企业出海提出了哪些真知灼见&#xff1f; 十年蓄势十年爆…

yolov8中的C2f层

在代码注释中看到C2f其实是 CSP Bottleneck with 2 convolutions 找来CSP的图 大致是把一个output按channel拆成2部分&#xff0c;其中一部分不动&#xff0c; 另一部分过conv&#xff0c;再拼回去&#xff0c; 因为是with 2 convolutions, 会有2个conv. 下面根据代码来走一…

P-One一站式性能测试平台如何安装在国产化操作系统上运行

PerformanceOne&#xff08;简称&#xff1a;P-One&#xff09;是泽众软件自主研发的一套一站式性能测试平台软件产品。 该产品采用 B/S 架构开发&#xff0c;实现了集管理、设计、压测、监控以及分析于一体的全方位性能测试解决方案。可有效提升性能测试技术能力&#xff0c;…

【unity】基础入门 编译错误排查与调试方法

基础入门 编译错误排查与调试方法 一、常见编译错误原因1、环境问题2、代码命名问题二、代码调试方法1、基础调试方法2、高级玩法3、unity调试工具插件一、常见编译错误原因 1、环境问题 1、Win11系统不兼容部分unity版本 考虑换系统吧! 2、可能是系统权限问题,访问不到部分…

经济学人特稿:你应该送孩子去私立学校吗? | 经济学人20230610版社论双语精翻

“升学季”特稿&#xff1a;2023年6月10日《经济学人》周报封面文章《送孩子去私立学校——值吗?》&#xff08;Are private schools worth it?&#xff09; International | Studying for success 为了成功而学习 Should you send your children to private school? 你应该…

跨境电商对于撸卡、撸货、采退都需要哪些技术要求

在当前跨境电商环境下&#xff0c;从事撸卡、撸货或者采退等业务的人员日益增多。然而&#xff0c;由于大部分人使用的环境系统相对简单&#xff0c;例如云手机、一键新机工具IP、指纹浏览器IP、虚拟机等&#xff0c;缺乏足够复杂的防护机制&#xff0c;因此&#xff0c;经常会…

马拉松资讯获取及报名渠道分享

1、马拉松赛事 1.1 马拉松赛事组别 马拉松赛事分为全程马拉松&#xff08;42.195公里&#xff09;、半程马拉松&#xff08;21.0975公里&#xff09;、短程跑&#xff08;健康跑、亲子跑、家庭跑之类的&#xff09;这几个类别&#xff0c;大型田协认证赛事三种类型都有&#…

Spark大数据处理学习笔记(3.2.1)掌握RDD算子

该文章主要为完成实训任务&#xff0c;详细实现过程及结果见【http://t.csdn.cn/FArNP】 文章目录 一、准备工作1.1 准备文件1. 准备本地系统文件2. 把文件上传到 1.2 启动Spark Shell1. 启动HDFS服务2. 启动Spark服务3. 启动Spark Shell 二、掌握转换算子2.1 映射算子 - map()…

C#编写VBScript的Com组件

背景 前段时间学习了一下vbsript&#xff0c;做了马踏棋盘的广度搜索算法题&#xff0c;线性回归的深度学习算法题&#xff0c;虽然是做出来了&#xff0c;但是总感觉不太方便&#xff0c;很多细节都需要自己去实现&#xff0c;这样很不方便&#xff0c;不容易让大家更简单上手…

海外新闻稿发布平台TOP10,媒介易为你盘点热门选择!

海外新闻稿发布是企业在海外市场推广的重要手段之一&#xff0c;通过选择合适的发布媒体&#xff0c;可以提升品牌知名度、扩大影响力&#xff0c;并吸引更多目标受众的关注。然而&#xff0c;由于海外市场的多样性和媒体渠道的繁多&#xff0c;选择适合的海外新闻稿发布媒体成…

windows 服务程序和桌面程序集成(七)效果演示及源程序下载

系列文章目录链接 windows 服务程序和桌面程序集成&#xff08;一&#xff09;概念介绍windows 服务程序和桌面程序集成&#xff08;二&#xff09;服务程序windows 服务程序和桌面程序集成&#xff08;三&#xff09;UDP监控工具windows 服务程序和桌面程序集成&#xff08;四…

Spring集成Kafka

前言 我负责的其中一个项目&#xff0c;接口的交互量在千万级/d&#xff0c;所以要存储大量的日志&#xff0c;为了防止日志的存储影响到系统的性能&#xff0c;所以在技术选型就决定了使用Kafka中间件和一个日志存储系统来负责日志的存储。 使用Kafka 的优点&#xff1a; 1.…

【HTMLCSS】设置导航栏

&#x1f38a;专栏【 前端易错合集】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 大一同学小吉&#xff0c;欢迎并且感谢大家指出我的问题&#x1f970; 目录 &#x1f354;效果 &#x1f339;代码&#xff1a; &…