IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity 知识点 - 3D游戏 - 视角跟随和键盘移动 -> 正文阅读

[游戏开发]Unity 知识点 - 3D游戏 - 视角跟随和键盘移动

前言:

1.转动视角

参考教程:《unity 的Cinemachine组件运用

  • 搜索了一下,发现原来 cinemachine插件可创建freeLook虚拟相机,这个相机可以直接实现转动视角的效果。
  • 可调参数有很多,下面列举一些我明白意思且 认为重要的。
  1. Follow:跟随对象。
  2. Lens - 视野:默认的很小,几乎大头贴,第一人称了,需要拉远一点。
  3. X/Y Axis - 值:上下高度,可以设置默认值。运行时会变动。
  4. X/Y Axis - Speed:转动的速度,相当于跟随的灵敏度。
  5. X/Y Axis - Input Axis Name:输入的变量,默认是鼠标的移动,还可以设置成方向键。
  6. X/Y Axis - Input Axis Value - Invenrt:这个是反向的勾选,默认的可能反向,方向不对可以修改调整。

2.键盘移动

参考代码:《Unity 键盘WASD 实现物体移动

  • A:原本我是想着模仿2D入门教程里的做法,赋值速度的。但是发现角色对象没有刚体这个组件(突然好奇是怎么立在地图上的),没有速度的属性……

  • B:后来我想到,既然本来就自带了导航组件,或许应该顺着使用导航来实现键盘移动。只需要每次按键就导航一小段距离就好了。

  • A: 直接使用读取按键输入,然后叠加在坐标上,就可以实现移动了。但因为坐标系的问题,我按W向前,并不是向前,而是朝正X轴方向轴……这就相当于只能轴8个方向了。真正要实现的应该是我视角朝哪边,就往哪边前进。

  • B:运用简单的数学知识——三角函数和反三角函数。我可以根据虚拟相机和角色的坐标,计算出二者相当于绝对坐标系的夹角,然后再输出。代码实现后就是如下效果。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class MouseManager : MonoBehaviour
{
    public float moveSpeed; // 移动速度
    public Transform playerTransform, camTransform; 

	// ...略一些非重点代码,导航相关的

	void Update()
	{
		KeyboardToMove(); // 运动控制
	}
	
	// ...略一些非重点代码,导航相关的
	
	// 键盘移动
	public void KeyboardToMove()
	{
		float xPosition = playerTransform.position.x; // 原坐标
		float zPosition = playerTransform.position.z;	
		
        float ad_input = Input.GetAxisRaw("Horizontal"); // 读取键盘输入,返回-1、0、1
		float ws_input = Input.GetAxisRaw("Vertical");	
		
        if(ad_input != 0 || ws_input != 0) // 如果有输入
		{
			double alpha = (playerTransform.position.x - camTransform.position.x);
			alpha /= (playerTransform.position.z - camTransform.position.z);
			alpha = Math.Atan(alpha); // 求反正切,返回弧度制
			
			if((playerTransform.position.z - camTransform.position.z) < 0)  // 这个是重点
			{
				ad_input = -ad_input;
				ws_input = -ws_input; // 发现一个数学问题,当z轴差为负数时,操作会反向……懒得推导为什么了
			}
			
			xPosition += ws_input * Time.deltaTime * moveSpeed * (float)Math.Sin(alpha); // 前后输入
			zPosition += ws_input * Time.deltaTime * moveSpeed * (float)Math.Cos(alpha);

			xPosition += ad_input * Time.deltaTime * moveSpeed * (float)Math.Sin(alpha + Math.PI / 2); // 左右输入
			zPosition += ad_input * Time.deltaTime * moveSpeed * (float)Math.Cos(alpha + Math.PI / 2); // 注意角度要加PI/2
			
			Vector3 v3 = new Vector3(xPosition, playerTransform.position.y, zPosition); // 合成坐标
			OnMouseClicked?.Invoke(v3); // 调用方法,将坐标输出到导航系统 
		}
	}
}

一开始测试sincos时弄得自己头昏目眩,因为懒得细节的每一个方向都推导出来,好麻烦。我就一个一个试,反正就2种情况。太不严谨了,所以导致了一个错误。

  • A:一开始是先只有前后键输入,测试是否成功。一开始还好,但发现时不时就会方向混乱。

  • B:根据之前写ros坐标系的经验,我推断是坐标的正负问题。然后反复测试观察(懒得动笔算数学),发现当朝向面向Z轴负半轴时,WS键的功能会交互。W是后退,S是前进。所以就加了一个判断,但z轴差为负时就取相反数。

  • A:然后添加左右键输入的功能,测试发现更加混乱了。

  • B:稍微推导了一下,当夹角为零时,左右前进就相当于夹角为90°的前后前进。所以加了PI/2。同时左右也有刚刚的问题,所以当面向Z负半轴就取相反数。

3.完成

  • 欧耶,成就感满满。
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-11-16 19:09:43  更:2021-11-16 19:11:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 23:47:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码