参考文章目录
1.【游戏开发实战】下载原神模型,PMX转FBX,导入到Unity中,卡通渲染,绑定人形动画(附Demo工程)
2.【Unity】如何编写鼠标拖拽移动物体
3.【unity】几种常用的拖拽方法(内置方法 + 接口 + Event Trigger组件)
4.【Unity】UGUI的EventSystem(事件系统)组件的介绍及使用
5.【Unity】鼠标控制3D物体的移动、旋转、缩放
6.【Unity】制作桌宠核心代码
7.【Unity】Unity 制作萌系live2d桌宠:屏幕自适应+交互
文章目录
前言
~首先非常感谢各位大佬们的分享,在他们的基础上我才能写出自己的桌宠程序。如有侵权,联系马上删改。
~其次我在他们教程的基础上进行了修改。下面是我制作的流程与他们的不同之处。
一、导入模型
首先根据第一篇文章下载安装好blender2.93版,我是从官网下载的,国内社区的没找到。
在使用cast修正模型fix model的时候,取消勾选Keep Upper Chest,不然模型脖子的骨架会发生折叠。
文章博主的Misc插件指的是杂项插件
MMD插件应该可以修正,但目前还没有弄明白如何使用该插件。
二、配置动画Animator
本人的设计的桌宠主要有两个动作,用鼠标动作进行动作切换。
在Mixamo下载了动作之后,导入unity按照文章1的配置方式先设置好Rig中Animation Type的模式
随后在导入的fbx中找到Animation拖入创建的Animator中,(Animator如果没生成,可以主动创建一个,添加到模型中即可)
这里我拉入了两个Animation并在Parameters中设置了一个bool变量chance来控制动作的切换
三、鼠标事件控制(参考文章2-5)
1.设计鼠标单击切换桌宠动作功能
采用的是简单的鼠标按键的点击事件
代码如下:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class NewBehaviourScript : MonoBehaviour
{
[SerializeField] Animator animator;//动作切换
bool chance = false;
void Update()
{
if (Input.GetMouseButton(0))
{
animator.SetBool("chance", chance);
chance = !chance;
}
}
}
2.设计鼠标左键拖拽桌宠功能
- 这里有三种实现方式,一是利用Button触发拖动事件,模型跟随Button移动
代码如下:
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UIElements;
public class DragObject : MonoBehaviour, IDragHandler
{
public GameObject gameObject;
public void OnDrag(PointerEventData eventData)
{
this.transform.position = eventData.position;
gameObject.transform.position = new Vector3( eventData.position.x/1920*6-3, eventData.position.y/1080*3.4f-2f,0);
}
}
把脚本挂载到Button上,为了美观可以设置按钮图案的透明度为0
- 直接在模型上使用鼠标拖动事件
代码如下:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class NewBehaviourScript : MonoBehaviour
{
Vector3 mouse_position;
void OnMouseDrag()
{
mouse_position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
transform.position = new Vector3(mouse_position.x, mouse_position.y - 1.25f, 0);
}
}
在模型上加载脚本即可
- 使用射线碰撞检测Raycast,这个功能模型必须添加Coliider组件,否则无法正常触发
代码如下:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class NewBehaviourScript : MonoBehaviour
{
public Camera game_camera;
public Collider coll;
Vector3 offset;
Vector3 mouseStarPos;
float depth;
void Start()
{
coll = GetComponent<Collider>();
}
void Update()
{
Ray ray = game_camera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (coll.Raycast(ray, out hit, 10.0f))
{
if (Input.GetMouseButtonDown(0))
{
depth = hit.distance;
Vector3 mouseStartPos = ray.origin + ray.direction * depth;
offset = transform.position - mouseStartPos;
}
if (Input.GetMouseButton(0))
{
transform.position = ray.origin + ray.direction * depth + offset;
}
}
}
}
这里的代码是文章2作者在评论区中给出的,但实际运行时如果鼠标拖动太快,程序帧数跟不上时容易出现拖不动的情况。
以上三种拖拽方法中模型坐标计算都略有区别,第一种是根据屏幕像素点大小转化过来的,程序中屏幕大小设置为1920*1080,归一化后乘以模型移动范围。第二种是直接利用内置坐标系变换函数。
3.设计鼠标右键旋转桌宠功能
把旋转的代码放入射线碰撞检测Raycast中即可
整合所有鼠标事件代码如下:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
[AddComponentMenu("Event/Event System")]
public class NewBehaviourScript : MonoBehaviour
{
public Camera game_camera;
[SerializeField] public Collider coll;
Vector3 offset;
float depth;
private float ySpeed = 120.0f; //旋转视角时相机y轴转速
private int yMinLimit = -360;
private int yMaxLimit = 360;
private float x = 0.0f; //存储相机的euler角
private float y = 0.0f; //存储相机的euler角
[SerializeField] Animator animator;//动作切换
bool chance = false;
void Start()
{
coll = GetComponent<Collider>();
}
void Update()
{
if (Input.GetMouseButton(0))
{
animator.SetBool("chance", chance);
chance = !chance;
}
Ray ray = game_camera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (coll.Raycast(ray, out hit, 10.0f))
{
if (Input.GetMouseButton(1))
{
y -= Input.GetAxis("Mouse Y") * ySpeed*0.2f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
transform.rotation= Quaternion.Euler(0, y+180, 0);
}
}
}
void OnMouseDrag()
{
mouse_position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
transform.position = new Vector3(mouse_position.x, mouse_position.y - 1.25f, 0);
}
static float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
}
四、桌面背景透明度设置
按照文章6进行设置,这篇文章是在设置窗口透明度上有些bug,会有人物边缘不清晰的问题
按照文章7进行设置,实测这个效果更好
如果程序运行后背景是黑的,则做以上设置。
总结
实现了一个简单的原神桌宠,具有拖拽,旋转,动作切换功能。但目前实现功能较少,渲染结果会出现模型边缘锯齿的情况,计划下一步添加更多功能
一位在读的研究生,刚接触unity3D,希望大家一起学习,欢迎大家评论区留言。