当前位置:网站首页>Unity 制作旋转门 推拉门 柜门 抽屉 点击自动开门效果 开关门自动播放音效 (附带编辑器扩展代码)
Unity 制作旋转门 推拉门 柜门 抽屉 点击自动开门效果 开关门自动播放音效 (附带编辑器扩展代码)
2022-07-04 16:17:00 【唐沢】
简易的门制作
对于一个新手来说,这个工具是最好的选择
上一篇关于开关门的文章相对于复杂,感兴趣的可以查看上篇开关门制作
优点
- 挂载就能使用
- 控制面板一看就懂(全是中文)
- 简单的调试就能获得自己想要的效果
- 易懂且易修改的代码
面板
参数
- 锁:勾选后不能对门进行操作
- 声音:激活时自动播放
- 激活:测试开关门
- 查看结果位置:按住查看结果,松开返回
旋转门的使用不做介绍
推拉门(推拉抽屉):
- 起始位置:门的初始位置
- 结束位置:门要移动的位置
- 得到位置按钮:当你在场景中调整门的位置后,把当前门的位置赋值到左侧
代码
挂载之后会自动添加Audio Source组件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(AudioSource))]
public class Door_Interaction : MonoBehaviour
{
public enum doorType {
RotatingDoor = 0, SlidingDoor = 1 }
public doorType doorMovementType;
public bool open;
public bool locked;
public float rotateAngle = 90;
public float speed = 1;
public enum axis {
X = 0, Y = 1, Z = 2 }
public axis rotateAxis = axis.Y;
public Vector3 startingPosition;
public Vector3 endingPosition;
public AudioClip startClip;
public AudioClip endClip;
private AudioSource sound;
public Quaternion originRotation;
public Quaternion openRotation;
private float r;
private bool opening;
[Tooltip("激活测试")]
public bool activate = false;
void Start()
{
InitRotation();
sound = GetComponent<AudioSource>();
r = 0;
}
public void InitRotation()
{
originRotation = transform.rotation;
openRotation = originRotation;
if (rotateAxis == axis.Y)
{
openRotation = Quaternion.Euler(new Vector3(originRotation.eulerAngles.x, originRotation.eulerAngles.y + rotateAngle, originRotation.eulerAngles.z));
}
else if (rotateAxis == axis.X)
{
openRotation = Quaternion.Euler(new Vector3(originRotation.eulerAngles.x + rotateAngle, originRotation.eulerAngles.y, originRotation.eulerAngles.z));
}
else if (rotateAxis == axis.Z)
{
openRotation = Quaternion.Euler(new Vector3(originRotation.eulerAngles.x, originRotation.eulerAngles.y, originRotation.eulerAngles.z + rotateAngle));
}
}
void Update()
{
if (activate)
{
activate = false;
if (opening == false && locked == false)
{
open = !open;
r = 0;
opening = true;
}
}
if (opening)
{
ChangeState(open);
}
}
void ChangeState(bool State)
{
Quaternion quaternion;
Vector3 vector3;
if (State)
{
quaternion = openRotation;
vector3 = endingPosition;
if (startClip!=null&& r==0)
{
sound.clip = startClip;
sound.Play();
}
}
else
{
quaternion = originRotation;
vector3 = startingPosition;
if (endClip != null && r == 0)
{
sound.clip = endClip;
sound.Play();
}
}
r += Time.deltaTime * speed;
if (doorMovementType == doorType.RotatingDoor)
{
if (Quaternion.Angle(quaternion, transform.rotation) > 0.1F)
{
transform.rotation = Quaternion.Slerp(transform.rotation, quaternion, r);
}
else
{
transform.rotation = quaternion;
r = 0;
opening = false;
}
}
else if (doorMovementType == doorType.SlidingDoor)
{
if (Vector3.Distance(transform.localPosition, vector3) > 0.005F)
{
transform.localPosition = Vector3.Lerp(transform.localPosition, vector3, r);
}
else
{
transform.localPosition = vector3;
r = 0;
opening = false;
}
}
}
}
编辑器扩展代码
需要注意!这个代码必须放在Editor文件下才能正常使用,Unity会自己处理Editor文件夹,就像Resources文件夹一样
我之前写的通用相机控制器也是一样的使用方法
感兴趣的可以查看通用相机控制器
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(Door_Interaction)), CanEditMultipleObjects]
public class Door_Interaction_Editor : Editor
{
private SerializedProperty open;
private SerializedProperty locked;
private SerializedProperty rotateAngle;
private SerializedProperty speed;
private SerializedProperty rotateAxis;
private SerializedProperty startingPosition;
private SerializedProperty endingPosition;
private SerializedProperty activate;
private SerializedProperty startClip;
private SerializedProperty endClip;
private GUIStyle defaultStyle = new GUIStyle();
public void OnEnable()
{
open = serializedObject.FindProperty("open");
locked = serializedObject.FindProperty("locked");
rotateAngle = serializedObject.FindProperty("rotateAngle");
speed = serializedObject.FindProperty("speed");
rotateAxis = serializedObject.FindProperty("rotateAxis");
startingPosition = serializedObject.FindProperty("startingPosition");
endingPosition = serializedObject.FindProperty("endingPosition");
activate = serializedObject.FindProperty("activate");
startClip = serializedObject.FindProperty("startClip");
endClip = serializedObject.FindProperty("endClip");
}
bool IsButtonDown = false;
Vector3 CurrentPosition= Vector3.zero;
Quaternion CurrentRotation = Quaternion.identity;
public override void OnInspectorGUI()
{
serializedObject.Update();
var myScript = target as Door_Interaction;
var doorGUIContent = new GUIContent("门类型", "选择不同门的类型参数也有所改变");
GUIContent[] doorOptions;
doorOptions = new[] {
new GUIContent("旋转门"), new GUIContent("推拉门") };
myScript.doorMovementType = (Door_Interaction.doorType)EditorGUILayout.Popup(doorGUIContent, (int)myScript.doorMovementType, doorOptions);
EditorGUILayout.PropertyField(open,new GUIContent("当前状态"));
EditorGUILayout.PropertyField(locked, new GUIContent("锁"));
EditorGUILayout.PropertyField(speed, new GUIContent("执行速度"));
EditorGUILayout.PropertyField(startClip, new GUIContent("打开时的声音"));
EditorGUILayout.PropertyField(endClip, new GUIContent("关闭时的声音"));
EditorGUILayout.PropertyField(activate, new GUIContent("激活"));
GUILayout.Space(20);//间隔
if (myScript.doorMovementType == Door_Interaction.doorType.RotatingDoor) {
EditorGUILayout.PropertyField(rotateAngle, new GUIContent("旋转角度"));
EditorGUILayout.PropertyField(rotateAxis, new GUIContent("轴", "门的旋转轴。 默认是Y "));
GUILayout.Space(20);//间隔
if (GUILayout.RepeatButton(new GUIContent("查看结束位置", "在视图中查看结束位置")))
{
if (IsButtonDown == false)
{
IsButtonDown = true;
myScript.InitRotation();
CurrentRotation = myScript.transform.localRotation;
}
myScript.transform.rotation = myScript.openRotation;
}
else
{
if (IsButtonDown)
{
IsButtonDown = false;
myScript.transform.localRotation = CurrentRotation;
}
}
} else if (myScript.doorMovementType == Door_Interaction.doorType.SlidingDoor) {
defaultStyle.alignment = TextAnchor.UpperCenter; //字体对齐方式: 水平靠左,垂直居中
defaultStyle.normal.textColor = Color.yellow; //字体颜色:黄色
defaultStyle.fontSize = 15; //字体大小: 20
GUILayout.Label("起始位置", defaultStyle);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PropertyField(startingPosition, new GUIContent(""));
if (GUILayout.Button(new GUIContent("得到位置", "将当前的局部坐标赋值给开始位置")))
{
myScript.startingPosition = myScript.transform.localPosition;
}
EditorGUILayout.EndHorizontal();
GUILayout.Label("结束位置", defaultStyle);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PropertyField(endingPosition, new GUIContent(""));
if (GUILayout.Button(new GUIContent("得到位置", "将当前的局部坐标赋值给结束位置")))
{
myScript.endingPosition = myScript.transform.localPosition;
}
EditorGUILayout.EndHorizontal();
GUILayout.Space(20);//间隔
if (GUILayout.RepeatButton(new GUIContent("查看结束位置", "在视图中查看结束位置")))
{
if (IsButtonDown==false)
{
IsButtonDown = true;
CurrentPosition = myScript.transform.localPosition;
}
myScript.transform.localPosition = myScript.endingPosition;
}
else
{
if (IsButtonDown)
{
IsButtonDown = false;
myScript.transform.localPosition = CurrentPosition;
}
}
}
serializedObject.ApplyModifiedProperties();//顾名思义 应用修改的属性
if (GUI.changed == true) {
EditorUtility.SetDirty(target);//这个函数告诉引擎,相关对象所属于的Prefab已经发生了更改。
}
}
}
别要Demo了,按照流程赋值粘贴代码就能用 !
边栏推荐
- 7 RSA Cryptosystem
- Redis master-slave replication
- Zebras are recognized as dogs, and the reason for AI's mistakes is found by Stanford
- Superscalar processor design yaoyongbin Chapter 5 instruction set excerpt
- Image retrieval
- How to test MDM products
- gatling 之性能测试
- Once the "king of color TV", he sold pork before delisting
- ARTS_20220628
- 我写了一份初学者的学习实践教程!
猜你喜欢
Perfectly integrated into win11 style, Microsoft's new onedrive client is the first to see
明星开店,退,退,退
Weima, which is going to be listed, still can't give Baidu confidence
CocosCreator事件派發使用
创业两年,一家小VC的自我反思
Internet addiction changes brain structure: language function is affected, making people unable to speak neatly
DB-Engines 2022年7月数据库排行榜:Microsoft SQL Server 大涨,Oracle 大跌
Superscalar processor design yaoyongbin Chapter 5 instruction set excerpt
The money circle boss, who is richer than Li Ka Shing, has just bought a building in Saudi Arabia
Interpretation of data security governance capability evaluation framework 2.0, the fourth batch of DSG evaluation collection
随机推荐
Summary of subsidy policies across the country for dcmm certification in 2022
DB-Engines 2022年7月数据库排行榜:Microsoft SQL Server 大涨,Oracle 大跌
The company needs to be monitored. How do ZABBIX and Prometheus choose? That's the right choice!
Numpy 的仿制 2
mysql5.7安装教程图文详解
Detectron2 installation method
Once the "king of color TV", he sold pork before delisting
General environmental instructions for the project
设置窗体透明 隐藏任务栏 与全屏显示
Device interface analysis of the adapter of I2C subsystem (I2C dev.c file analysis)
What if Kaili can't input Chinese???
上市公司改名,科学还是玄学?
Superscalar processor design yaoyongbin Chapter 5 instruction set excerpt
curl 命令妙用
明星开店,退,退,退
内核中时间相关的知识介绍
Superscalar processor design yaoyongbin Chapter 7 register rename excerpt
Clever use of curl command
78岁华科教授冲击IPO,丰年资本有望斩获数十倍回报
7 RSA Cryptosystem