当前位置:网站首页>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章:多元函数的微分学
- 通过事件绑定实现动画效果
- Analysis of I2C adapter driver of s5pv210 chip (i2c-s3c2410. C)
- Rainfall warning broadcast automatic data platform bwii broadcast warning monitor
- Device interface analysis of the adapter of I2C subsystem (I2C dev.c file analysis)
- regular expression
- Make a grenade with 3DMAX
- The money circle boss, who is richer than Li Ka Shing, has just bought a building in Saudi Arabia
- 表情包坑惨职场人
- 一直以为做报表只能用EXCEL和PPT,直到我看到了这套模板(附模板)
猜你喜欢
使用3DMAX制作一枚手雷
超标量处理器设计 姚永斌 第7章 寄存器重命名 摘录
股价大跌、市值缩水,奈雪推出虚拟股票,深陷擦边球争议
Zhijieyun - meta universe comprehensive solution service provider
我写了一份初学者的学习实践教程!
数学分析_笔记_第7章:多元函数的微分学
RecastNavigation 之 Recast
Self reflection of a small VC after two years of entrepreneurship
90后开始攒钱植发,又一个IPO来了
With the stock price plummeting and the market value shrinking, Naixue launched a virtual stock, which was deeply in dispute
随机推荐
Heartless sword Chinese translation of Elizabeth Bishop's a skill
The top half and bottom half of the interrupt are introduced and the implementation method (tasklet and work queue)
78 year old professor Huake impacts the IPO, and Fengnian capital is expected to reap dozens of times the return
Analysis of I2C adapter driver of s5pv210 chip (i2c-s3c2410. C)
内核中时间相关的知识介绍
估值900亿,超级芯片IPO来了
Face_ Attendance statistics of recognition face recognition
TCP两次挥手,你见过吗?那四次握手呢?
Win32 API access route encrypted web pages
数学分析_笔记_第7章:多元函数的微分学
Win32 API 访问路由的加密网页
【系统分析师之路】第七章 复盘系统设计(结构化开发方法)
【HCIA持续更新】WLAN概述与基本概念
With the stock price plummeting and the market value shrinking, Naixue launched a virtual stock, which was deeply in dispute
为啥有些线上演唱会总是怪怪的?
Developers, MySQL column finish, help you easily from installation to entry
Master the use of auto analyze in data warehouse
Easy to use map visualization
ARTS_20220628
With an estimated value of 90billion, the IPO of super chip is coming