Unity3D中物体移动拖影

2023-10-08 22:30
文章标签 移动 物体 unity3d 拖影

本文主要是介绍Unity3D中物体移动拖影,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

两个脚本即可实现

脚本一:获取对象下的skinMeshRenderer或者meshRenderer组件

using UnityEngine;
using System.Collections;
using System.Collections.Generic;namespace DragonRun
{[ExecuteInEditMode]public class PlayerShadow : MonoBehaviour{public Shader curShader;private List<Vector3> offsets = new List<Vector3>(); // 存储前几帧的坐标private List<Material> mats = new List<Material>(); // 存储人物的材质,用于给shader传参数// Use this for initializationvoid Start(){offsets.Add(transform.position);offsets.Add(transform.position);offsets.Add(transform.position);offsets.Add(transform.position);var skinMeshRenderer = gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();foreach (var mr in skinMeshRenderer)mats.Add(mr.material);var meshRenderer = gameObject.GetComponentsInChildren<MeshRenderer>();foreach (var mr in meshRenderer)mats.Add(mr.material);foreach (var mat in mats)mat.shader = curShader;}private int frame = 3;// Update is called once per framevoid Update(){this.frame--;if (this.frame <= 0){foreach (var mat in mats) // 每帧将之前的位置传入shader中{mat.SetVector("_Offset0", offsets[3] - transform.position);mat.SetVector("_Offset1", offsets[2] - transform.position);mat.SetVector("_Offset2", offsets[1] - transform.position);mat.SetVector("_Offset3", offsets[0] - transform.position);}offsets.Add(transform.position);offsets.RemoveAt(0);this.frame = 99;//此处修改控制残影显示的间隔}}}
}

脚本二:构建标准Shader脚本,根据上面脚本中记录的帧信息进行残影显示

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "Custom/Ghost" {Properties{_MainTex("Main Tex", 2D) = "white" {}_Offset0("Offset 0", vector) = (0, 0, 0, 0) // 这里只显示4个残影,所以传入4个偏移值_Offset1("Offset 1", vector) = (0, 0, 0, 0)_Offset2("Offset 2", vector) = (0, 0, 0, 0)_Offset3("Offset 3", vector) = (0, 0, 0, 0)}CGINCLUDE
#include "UnityCG.cginc"sampler2D _MainTex;float4 _Offset0;float4 _Offset1;float4 _Offset2;float4 _Offset3;struct v2f {float4 pos : POSITION;float2 uv : TEXCOORD0;};v2f vert_normal(appdata_base v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.uv = v.texcoord;return o;}v2f vert_offset_1(appdata_base v) {v2f o;float4 pos = mul(unity_ObjectToWorld, v.vertex);o.pos = mul(UNITY_MATRIX_VP, pos + _Offset0);o.uv = v.texcoord;return o;}v2f vert_offset_2(appdata_base v) {v2f o;float4 pos = mul(unity_ObjectToWorld, v.vertex);o.pos = mul(UNITY_MATRIX_VP, pos + _Offset1);o.uv = v.texcoord;return o;}v2f vert_offset_3(appdata_base v) {v2f o;float4 pos = mul(unity_ObjectToWorld, v.vertex);o.pos = mul(UNITY_MATRIX_VP, pos + _Offset2);o.uv = v.texcoord;return o;}v2f vert_offset_4(appdata_base v) {v2f o;float4 pos = mul(unity_ObjectToWorld, v.vertex);o.pos = mul(UNITY_MATRIX_VP, pos + _Offset3);o.uv = v.texcoord;return o;}float4 frag_normal(v2f i) : COLOR{return tex2D(_MainTex, i.uv);}float4 frag_color(v2f i) : COLOR{ // 将残影的alpha值设为0.5float4 c;c = tex2D(_MainTex, i.uv);c.w = 0.5;return c;}ENDCGSubShader { // 这里用4个pass来渲染残影,第5个pass渲染自身Pass{ // 从最远的开始渲染ZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert_offset_4#pragma fragment frag_colorENDCG}Pass{ZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert_offset_3#pragma fragment frag_colorENDCG}Pass{ZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert_offset_2#pragma fragment frag_colorENDCG}Pass{ZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert_offset_1#pragma fragment frag_colorENDCG}Pass{ // 渲染自身,这时要开启 ZWriteBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert_normal#pragma fragment frag_normalENDCG}}FallBack "Diffuse"
}

最后,将PlayerShadow脚本挂在物体上,并将shader脚本赋值给Cur Shader变量,运行如下图所示:
在这里插入图片描述
注意:加上脚本后,未运行状态下,鼠标拖动物体也会产生拖影,因为存储了帧数据,并没有删除,只能迭代。

这篇关于Unity3D中物体移动拖影的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/168420

相关文章

双系统电脑中把Ubuntu装进外接移动固态硬盘的全过程

《双系统电脑中把Ubuntu装进外接移动固态硬盘的全过程》:本文主要介绍如何在Windows11系统中使用VMware17创建虚拟机,并在虚拟机中安装Ubuntu22.04桌面版或Ubunt... 目录一、首先win11中安装vmware17二、磁盘分区三、保存四、使用虚拟机进行系统安装五、遇见的错误和解决

使用FileChannel实现文件的复制和移动方式

《使用FileChannel实现文件的复制和移动方式》:本文主要介绍使用FileChannel实现文件的复制和移动方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录使用 FileChannel 实现文件复制代码解释使用 FileChannel 实现文件移动代码解释

Qt把文件夹从A移动到B的实现示例

《Qt把文件夹从A移动到B的实现示例》本文主要介绍了Qt把文件夹从A移动到B的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录如何移动一个文件? 如何移动文件夹(包含里面的全部内容):如何删除文件夹:QT 文件复制,移动(

Python重命名文件并移动到对应文件夹

《Python重命名文件并移动到对应文件夹》在日常的文件管理和处理过程中,我们可能会遇到需要将文件整理到不同文件夹中的需求,下面我们就来看看如何使用Python实现重命名文件并移动到对应文件夹吧... 目录检查并删除空文件夹1. 基本需求2. 实现代码解析3. 代码解释4. 代码执行结果5. 总结方法补充在

使用C#如何创建人名或其他物体随机分组

《使用C#如何创建人名或其他物体随机分组》文章描述了一个随机分配人员到多个团队的代码示例,包括将人员列表随机化并根据组数分配到不同组,最后按组号排序显示结果... 目录C#创建人名或其他物体随机分组此示例使用以下代码将人员分配到组代码首先将lstPeople ListBox总结C#创建人名或其他物体随机分组

我在移动打工的日志

客户:给我搞一下录音 我:不会。不在服务范围。 客户:是不想吧 我:笑嘻嘻(气笑) 客户:小姑娘明明会,却欺负老人 我:笑嘻嘻 客户:那我交话费 我:手机号 客户:给我搞录音 我:不会。不懂。没搞过。 客户:那我交话费 我:手机号。这是电信的啊!!我这是中国移动!! 客户:我不管,我要充话费,充话费是你们的 我:可是这是移动!!中国移动!! 客户:我这是手机号 我:那又如何,这是移动!你是电信!!

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物,今天我们实现一下人物实现移动和跳起,依次点击,我们准备创建一个C#文件 创建好我们点击进去,就会跳转到我们的Vision Studio,然后输入这些代码 using UnityEngine;public class Move : MonoBehaviour // 定义一个名为Move的类,继承自MonoBehaviour{private Rigidbo

Unity3D自带Mouse Look鼠标视角代码解析。

Unity3D自带Mouse Look鼠标视角代码解析。 代码块 代码块语法遵循标准markdown代码,例如: using UnityEngine;using System.Collections;/// MouseLook rotates the transform based on the mouse delta./// Minimum and Maximum values can

简单的角色响应鼠标而移动

actor类 //处理移动距离,核心是找到角色坐标在世界坐标的向量的投影(x,y,z),然后在世界坐标中合成,此CC是在地面行走,所以Y轴投影始终置为0; using UnityEngine; using System.Collections; public class actor : MonoBehaviour { public float speed=0.1f; CharacterCo

Unity3D 运动之Move函数和translate

CharacterController.Move 移动 function Move (motion : Vector3) : CollisionFlags Description描述 A more complex move function taking absolute movement deltas. 一个更加复杂的运动函数,每次都绝对运动。 Attempts to