Unity引擎制作球形地面

2024-08-23 12:04

本文主要是介绍Unity引擎制作球形地面,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Unity引擎制作球形地面3

大家好,我是阿赵。
  之前有个朋友问我,有些游戏,角色好像走在一个球形的地面上,离角色远的东西会往下沉,直到看不见。
在这里插入图片描述

  这种效果的做法肯定不止一种的。
  最直观的做法,如果本身每张地图的范围很小,是固定只能走一定的圆弧范围的地面。这种情况我觉得直接做一个弯曲的3D模型作为地表,也可以做到。
  不过这种做弯曲3D模型的方式,局限性是比较大的,主要遇到的问题有这么几个:
1、 如果每张地图的大小不统一,需要的弧度可能也不统一,这样就变成了每个地图都要单独的去制作不同弧度的模型
2、 如果需要修改地图的弧度,可能面临着比较大工作量去修改模型
3、 游戏实际上还是二维坐标,但由于地图是有弧度的,所以需要做一个二维坐标向弯曲之后的地面映射的操作。
  后来我就建议朋友不要用这种3D模型的做法,而是用Shader控制顶点Y坐标的方法去实现。
  具体做法很简单,只需要用Shader控制模型顶点的Y坐标变化:
在这里插入图片描述

  实际有用的就是:
在这里插入图片描述

  这个部分是计算模型顶点坐标的,可以看出,我先获取了顶点的世界坐标,然后x和z是没有变化的,直接输入到最终的Append。
  然后有2个全局的变量:

1. rolePos
这个代表的是摄像机正在跟随的主角的坐标。
2. ballVal
地面的弯曲程度。

  接下来的计算很简单,把当前模型的顶点的z坐标,和主角的z坐标相减,然后乘以弯曲程度,得到一个需要向下偏移的值。最后用原来模型的y坐标减去这个偏移值就行了。用通俗简单一点的话来说,离主角z轴距离越远的顶点,需要往下偏移就越大,所以远处的东西就因为往下偏移,到完全看不见了。
在这里插入图片描述

  移动的实际过程可以参考视频:

Unity引擎制作球形地面2

  很明显,这个不是球形地面,而是圆柱形地面。如果真的想做到圆形地面的效果,其实也很简单,把x轴和z轴一起计算距离就行了,x和z离得远的,y就往下偏移得越多,看起来就是一个球形了。
在这里插入图片描述

在这里插入图片描述

  也许有些朋友会说,我这个不是正圆,或者说不是正圆弧的地面。但我想说的是,从效果上看,它已经完全达到我们的目的了,是不是正圆弧,并不是很重要吧。
  这样的做法好处很多:
1.不需要特殊的制作模型,一切还是按照平面的做法去做。
2.由于只是改变了高度,也即是y轴,x和z轴没有变化过,所以游戏里面的2d坐标逻辑,是完全不需要转换,就可以和场景上面的模型对应上。
3.可以随意的修改弯曲度。
  当然,缺点也是有的:
1、 由于需要控制所有场景物体的y坐标,所以项目里面所有使用到的shader都需要加y轴控制的代码。虽然我觉得项目里面所有的Shader应该是全部自己控制的,但对于很多朋友来说,他们的shader都不会自己写的,要么就是Unity自带的,要么是网上抄回来的。这种情况要全部shader自己控制是有点不切实际。
2、 对于地面模型的面数有一定的要求。由于控制的是顶点y坐标,所以如果地面的模型面数很少,比如隔几米才一个顶点,那么控制y坐标偏移,会出现不平滑的情况,其他物体要么浮在空中,要么嵌到地面。
最后分享一下ASE生成的代码,其实如果自己手写,代码可以简洁很多,无奈现在习惯了ASE的快速出效果,越来越懒了。

// Made with Amplify Shader Editor
// Available at the Unity Asset Store - http://u3d.as/y3X 
Shader "BallFloor"
{Properties{_MainTex("MainTex", 2D) = "white" {}_MainColor("MainColor", Color) = (1,1,1,0)[HideInInspector] _texcoord( "", 2D ) = "white" {}}SubShader{Tags { "RenderType"="Opaque" }LOD 100CGINCLUDE#pragma target 3.0ENDCGBlend OffAlphaToMask OffCull BackColorMask RGBAZWrite OnZTest LEqualOffset 0 , 0Pass{Name "Unlit"Tags { "LightMode"="ForwardBase" }CGPROGRAM#define ASE_ABSOLUTE_VERTEX_POS 1#ifndef UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX//only defining to not throw compilation error over Unity 5.5#define UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input)#endif#pragma vertex vert#pragma fragment frag#pragma multi_compile_instancing#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float4 color : COLOR;float4 ase_texcoord : TEXCOORD0;UNITY_VERTEX_INPUT_INSTANCE_ID};struct v2f{float4 vertex : SV_POSITION;#ifdef ASE_NEEDS_FRAG_WORLD_POSITIONfloat3 worldPos : TEXCOORD0;#endiffloat4 ase_texcoord1 : TEXCOORD1;UNITY_VERTEX_INPUT_INSTANCE_IDUNITY_VERTEX_OUTPUT_STEREO};uniform float3 rolePos;uniform float ballVal;uniform float4 _MainColor;uniform sampler2D _MainTex;uniform float4 _MainTex_ST;v2f vert ( appdata v ){v2f o;UNITY_SETUP_INSTANCE_ID(v);UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);UNITY_TRANSFER_INSTANCE_ID(v, o);float3 ase_worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;float temp_output_26_0 = ( ( ase_worldPos.x - rolePos.x ) * ballVal );float temp_output_4_0 = ( ( ase_worldPos.z - rolePos.z ) * ballVal );float3 appendResult2 = (float3(ase_worldPos.x , ( ase_worldPos.y - ( ( temp_output_26_0 * temp_output_26_0 ) + ( temp_output_4_0 * temp_output_4_0 ) ) ) , ase_worldPos.z));float3 worldToObj7 = mul( unity_WorldToObject, float4( appendResult2, 1 ) ).xyz;float3 VertexPos20 = worldToObj7;o.ase_texcoord1.xy = v.ase_texcoord.xy;//setting value to unused interpolator channels and avoid initialization warningso.ase_texcoord1.zw = 0;float3 vertexValue = float3(0, 0, 0);#if ASE_ABSOLUTE_VERTEX_POSvertexValue = v.vertex.xyz;#endifvertexValue = VertexPos20;#if ASE_ABSOLUTE_VERTEX_POSv.vertex.xyz = vertexValue;#elsev.vertex.xyz += vertexValue;#endifo.vertex = UnityObjectToClipPos(v.vertex);#ifdef ASE_NEEDS_FRAG_WORLD_POSITIONo.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;#endifreturn o;}fixed4 frag (v2f i ) : SV_Target{UNITY_SETUP_INSTANCE_ID(i);UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);fixed4 finalColor;#ifdef ASE_NEEDS_FRAG_WORLD_POSITIONfloat3 WorldPosition = i.worldPos;#endiffloat2 uv_MainTex = i.ase_texcoord1.xy * _MainTex_ST.xy + _MainTex_ST.zw;float4 color16 = ( _MainColor * tex2D( _MainTex, uv_MainTex ) );finalColor = color16;return finalColor;}ENDCG}}CustomEditor "ASEMaterialInspector"}
/*ASEBEGIN
Version=18500
1920;0;1920;1019;2189.778;742.377;1;True;True
Node;AmplifyShaderEditor.CommentaryNode;23;-1726.385,-493.2556;Inherit;False;1206.924;537.7661;Comment;12;20;7;3;2;8;4;10;5;1;11;25;27;VertexPos;1,1,1,1;0;0
Node;AmplifyShaderEditor.WorldPosInputsNode;1;-1608.486,-443.2556;Inherit;False;0;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
Node;AmplifyShaderEditor.Vector3Node;11;-1693.886,-266.1556;Inherit;False;Global;rolePos;rolePos;2;0;Create;True;0;0;False;0;False;0,0,0;-24.19481,0,-33.37932;0;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
Node;AmplifyShaderEditor.SimpleSubtractOpNode;25;-1428.778,-319.377;Inherit;False;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleSubtractOpNode;10;-1482.786,-221.6556;Inherit;False;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.RangedFloatNode;5;-1658.385,-38.65557;Inherit;False;Global;ballVal;ballVal;1;0;Create;True;0;0;False;0;False;0;0.1164894;0;0.2;0;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;26;-1312.778,-186.377;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;4;-1326.986,-81.95564;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;27;-1186.778,-201.377;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;8;-1099.42,-60.00696;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleAddOpNode;28;-960.7778,-115.377;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleSubtractOpNode;3;-1216.066,-293.2313;Inherit;False;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.CommentaryNode;18;-1715.685,-1092.361;Inherit;False;771.8348;492;;4;6;12;13;16;color;1,1,1,1;0;0
Node;AmplifyShaderEditor.DynamicAppendNode;2;-1110.767,-417.6276;Inherit;False;FLOAT3;4;0;FLOAT;0;False;1;FLOAT;0;False;2;FLOAT;0;False;3;FLOAT;0;False;1;FLOAT3;0
Node;AmplifyShaderEditor.SamplerNode;6;-1665.685,-830.3605;Inherit;True;Property;_MainTex;MainTex;0;0;Create;True;0;0;False;0;False;-1;None;None;True;0;False;white;Auto;False;Object;-1;Auto;Texture2D;8;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4
Node;AmplifyShaderEditor.ColorNode;12;-1632.685,-1042.361;Inherit;False;Property;_MainColor;MainColor;1;0;Create;True;0;0;False;0;False;1,1,1,0;1,1,1,0;True;0;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;13;-1357.685,-960.3605;Inherit;False;2;2;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;1;COLOR;0
Node;AmplifyShaderEditor.TransformPositionNode;7;-965.6563,-296.1759;Inherit;False;World;Object;False;Fast;True;1;0;FLOAT3;0,0,0;False;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
Node;AmplifyShaderEditor.RegisterLocalVarNode;20;-726.3401,-270.6392;Inherit;False;VertexPos;-1;True;1;0;FLOAT3;0,0,0;False;1;FLOAT3;0
Node;AmplifyShaderEditor.RegisterLocalVarNode;16;-1167.851,-940.5619;Inherit;False;color;-1;True;1;0;COLOR;0,0,0,0;False;1;COLOR;0
Node;AmplifyShaderEditor.GetLocalVarNode;17;-805.3762,-841.2354;Inherit;False;16;color;1;0;OBJECT;;False;1;COLOR;0
Node;AmplifyShaderEditor.GetLocalVarNode;22;-752.5753,-633.8202;Inherit;False;20;VertexPos;1;0;OBJECT;;False;1;FLOAT3;0
Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;0;-445.1787,-686.0229;Float;False;True;-1;2;ASEMaterialInspector;100;1;BallFloor;0770190933193b94aaa3065e307002fa;True;Unlit;0;0;Unlit;2;True;0;1;False;-1;0;False;-1;0;1;False;-1;0;False;-1;True;0;False;-1;0;False;-1;False;False;False;False;False;False;True;0;False;-1;True;0;False;-1;True;True;True;True;True;0;False;-1;False;False;False;True;False;255;False;-1;255;False;-1;255;False;-1;7;False;-1;1;False;-1;1;False;-1;1;False;-1;7;False;-1;1;False;-1;1;False;-1;1;False;-1;True;1;False;-1;True;3;False;-1;True;True;0;False;-1;0;False;-1;True;1;RenderType=Opaque=RenderType;True;2;0;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;1;LightMode=ForwardBase;False;0;;0;0;Standard;1;Vertex Position,InvertActionOnDeselection;0;0;1;True;False;;False;0
WireConnection;25;0;1;1
WireConnection;25;1;11;1
WireConnection;10;0;1;3
WireConnection;10;1;11;3
WireConnection;26;0;25;0
WireConnection;26;1;5;0
WireConnection;4;0;10;0
WireConnection;4;1;5;0
WireConnection;27;0;26;0
WireConnection;27;1;26;0
WireConnection;8;0;4;0
WireConnection;8;1;4;0
WireConnection;28;0;27;0
WireConnection;28;1;8;0
WireConnection;3;0;1;2
WireConnection;3;1;28;0
WireConnection;2;0;1;1
WireConnection;2;1;3;0
WireConnection;2;2;1;3
WireConnection;13;0;12;0
WireConnection;13;1;6;0
WireConnection;7;0;2;0
WireConnection;20;0;7;0
WireConnection;16;0;13;0
WireConnection;0;0;17;0
WireConnection;0;1;22;0
ASEEND*/
//CHKSM=14088912893801E38414D800F13E9F2C89931493

这篇关于Unity引擎制作球形地面的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

速了解MySQL 数据库不同存储引擎

快速了解MySQL 数据库不同存储引擎 MySQL 提供了多种存储引擎,每种存储引擎都有其特定的特性和适用场景。了解这些存储引擎的特性,有助于在设计数据库时做出合理的选择。以下是 MySQL 中几种常用存储引擎的详细介绍。 1. InnoDB 特点: 事务支持:InnoDB 是一个支持 ACID(原子性、一致性、隔离性、持久性)事务的存储引擎。行级锁:使用行级锁来提高并发性,减少锁竞争

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

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

Smarty模板引擎工作机制(一)

深入浅出Smarty模板引擎工作机制,我们将对比使用smarty模板引擎和没使用smarty模板引擎的两种开发方式的区别,并动手开发一个自己的模板引擎,以便加深对smarty模板引擎工作机制的理解。 在没有使用Smarty模板引擎的情况下,我们都是将PHP程序和网页模板合在一起编辑的,好比下面的源代码: <?php$title="深处浅出之Smarty模板引擎工作机制";$content=

OpenStack离线Train版安装系列—0制作yum源

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

OpenStack镜像制作系列5—Linux镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作

OpenStack镜像制作系列4—Windows Server2019镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录  CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作系

OpenStack镜像制作系列2—Windows7镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作系列

OpenStack镜像制作系列1—环境准备

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作

CSDN:OpenStack镜像制作教程指导(全)

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录,涉及基本环境准备、常见类型操作系统的镜像制作。 让你可以从零开始安装一个操作系统,并支持个性化制作OpenStack镜像。 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows

docker学习系列(四)制作基础的base项目镜像--jdk+tomcat

前面已经完成了docker的安装以及使用,现在我们要将自己的javaweb项目与docker结合 1.1准备jdk+tomcat软件 ​​我下载了apache-tomcat-7.0.68.tar.gz和jdk-7u79-linux-x64.tar.gz,存储于Linux机器的本地目录/usr/ect/wt/下(利用xshell上传)。利用linux命令 tar -zxvf apache-tom