unity中实现选中人物脚下显示圆形标识且完美贴合复杂地形(如弹坑) 的效果

        要实现人物脚下圆形 完美贴合复杂地形(如弹坑) 的效果,核心思路是 「动态生成贴合地面的 Mesh」 —— 即根据地面的高度场实时计算环形顶点的 Y 坐标,让每个顶点都 “贴” 在地面上。

核心逻辑:
  1. 确定环形范围:以人物脚部为中心,设定半径(如 1 米)和分段数(如 36 段,决定平滑度)。
  2. 生成环形顶点:在 XY 平面生成环形的顶点坐标(极坐标转笛卡尔坐标),然后 对每个顶点,实时获取其在地面的 Y 高度
  3. 构建 / 更新 Mesh:将顶点组成环形 Mesh(三角面或线框),每帧或人物移动时,重新计算顶点的 Y 坐标,确保贴合地面。
关键步骤实现:

       1. 地面高度采样(核心!)

  • 对 Unity Terrain:用 Terrain.SampleHeight(xzPosition) 直接获取地形高度。
  • 对 Mesh 地面:发射射线检测地面,获取 RaycastHit.point.y(更通用,支持任意模型地面)。
  • float GetGroundY(float x, float z) {Vector3 origin = new Vector3(x, characterFoot.position.y + 10f, z); // 从高处向下射Ray ray = new Ray(origin, Vector3.down);if (Physics.Raycast(ray, out RaycastHit hit, 20f, groundLayers)) {return hit.point.y; // 地面高度}return characterFoot.position.y; //  fallback
    }

    2. 动态生成环形 Mesh

  • 顶点生成:以中心为原点,用极坐标生成环形顶点的 X、Z 坐标,再通过上述方法获取 Y 坐标。
  • 三角面构建:将顶点组成三角面(填充环形)或线框(仅边缘)。
  • 实时更新:人物移动或地面变化时,重新计算顶点的 Y 坐标,更新 Mesh。
  • 示例代码(简化版,生成填充环形):
  • using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;using UnityEngine;public class tmp : MonoBehaviour
    {public Transform characterFoot;public float radius = 1f;public int segments = 36;public LayerMask groundLayers;private Mesh mesh;private Vector3[] vertices;private int[] triangles;private MeshFilter meshFilter;private MeshRenderer meshRenderer;void Start(){// 获取或添加MeshFilter组件meshFilter = GetComponent<MeshFilter>();if (meshFilter == null)meshFilter = gameObject.AddComponent<MeshFilter>();// 获取或添加MeshRenderer组件(用于显示网格)meshRenderer = GetComponent<MeshRenderer>();if (meshRenderer == null)meshRenderer = gameObject.AddComponent<MeshRenderer>();mesh = new Mesh();meshFilter.mesh = mesh;meshRenderer.sharedMaterial = new Material(Shader.Find("Universal Render Pipeline/Unlit"));UpdateMesh();}void UpdateMesh(){if (meshFilter == null || characterFoot == null) return;vertices = new Vector3[segments + 1];vertices[0] =new  Vector3(0, GetGroundY(0f, 0f) - characterFoot.position.y + 0.03f, 0);//vertices[0] = characterFoot.position;for (int i = 1; i <= segments; i++){float angle = Mathf.Deg2Rad * (i * 360f / segments);//float x = characterFoot.position.x + Mathf.Cos(angle) * radius;//float z = characterFoot.position.z + Mathf.Sin(angle) * radius;float x = Mathf.Cos(angle) * radius;float z =  Mathf.Sin(angle) * radius;float y = GetGroundY(x, z) - characterFoot.position.y+0.03f;vertices[i] = new Vector3(x, y, z);}triangles = new int[segments * 3];for (int i = 0; i < segments; i++){triangles[i * 3] = 0;      // 中心点triangles[i * 3 + 1] = i + 2;  // 下一个顶点triangles[i * 3 + 2] = i + 1;  // 当前顶点}triangles[segments * 3 - 2] = 1;   // 最后补上循环mesh.vertices = vertices;mesh.triangles = triangles;mesh.RecalculateNormals();Vector3[] normals = mesh.normals;mesh.normals = normals;}void Update(){if (meshFilter == null || vertices == null) return;//vertices[0] = new Vector3(0, GetGroundY(0f, 0f) - characterFoot.position.y + 0.03f, 0);for (int i = 0; i <= segments; i++){Vector3 pos = vertices[i];pos.y =  GetGroundY(pos.x, pos.z)- characterFoot.position.y + 0.03f;Debug.Log(pos.y);vertices[i] = pos;}mesh.vertices = vertices;mesh.RecalculateNormals();}float GetGroundY(float x, float z){if (characterFoot == null) return 0;// 3D射线起点:在角色脚下位置上方10单位处Vector3 origin = new Vector3(characterFoot.position.x+x, characterFoot.position.y + 10f, characterFoot.position.z+z);// 射线方向和长度Vector3 direction = Vector3.down;float maxDistance = 20f;// 绘制射线(仅在编辑模式和Play模式的Scene视图可见)// 颜色设为红色,持续0.1秒(足够看清且不会残留太久)Debug.DrawRay(origin, direction * maxDistance, Color.red, 0.1f);// 3D射线检测RaycastHit hit;if (Physics.Raycast(origin, direction, out hit, maxDistance, groundLayers)){// 绘制碰撞点标记(绿色小球)Debug.DrawRay(hit.point, Vector3.up * 0.5f, Color.green, 0.1f);return hit.point.y;}// 未检测到地面时,绘制射线终点标记(黄色小球)Debug.DrawRay(origin + direction * maxDistance, Vector3.up * 0.5f, Color.yellow, 0.1f);return characterFoot.position.y;}}

    3. 视觉优化(Shader + 纹理)

  • 纹理:使用带 Alpha 通道的环形纹理(中间透明,边缘黄色渐变)。
  • Shader:采用 Transparent shader,支持 Alpha 混合,可添加 自发光(Emission) 效果让环形更醒目。
  • 动画:通过 Shader 或代码实现边缘闪烁、颜色渐变(如选中时高亮)。

方案优势 vs 其他方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/92459.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/92459.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

引领GameFi 2.0新范式:D.Plan携手顶级财经媒体启动“龙珠创意秀”

在GameFi赛道寻求新突破的今天&#xff0c;一个名为Dragonverse Plan&#xff08;D.Plan&#xff09;的项目正以其独特的经济模型和宏大愿景&#xff0c;吸引着整个Web3社区的目光。据悉&#xff0c;D.Plan即将联合中文区顶级加密媒体金色财经与非小号&#xff08;Feixiaohao&a…

通信算法之307:fpga之时序图绘制

时序图绘制软件 一. 序言 在FPGA设计过程中&#xff0c;经常需要编写设计文档&#xff0c;其中&#xff0c;不可缺少的就是波形图的绘制&#xff0c;可以直接截取Vivado或者Modelsim平台实际仿真波形&#xff0c;但是往往由于信号杂乱无法凸显重点。因此&#xff0c;通过相应软…

计网学习笔记第3章 数据链路层(灰灰题库)

题目 11 单选题 下列说法正确的是______。 A. 路由器具有路由选择功能&#xff0c;交换机没有路由选择功能 B. 三层交换机具有路由选择功能&#xff0c;二层交换机没有路由选择功能 C. 三层交换机适合异构网络&#xff0c;二层交换机不适合异构网络 D. 路由器适合异构网络&…

SQL的LEFT JOIN优化

原sql&#xff0c;一个base表a,LEFT JOIN三个表抽数 SELECT ccu.*, ctr.*, om.*, of.* FROM ods.a ccu LEFT JOIN ods.b ctr ON ccu.coupon_code ctr.coupon_code AND ctr.is_deleted 0 LEFT JOIN ods.c om ON ctr.bill_code om.order_id AND om.deleted 0 LEFT JOIN ods.…

Redis 核心概念、命令详解与应用实践:从基础到分布式集成

目录 1. 认识 Redis 2. Redis 特性 2.1 操作内存 2.2 速度快 2.3 丰富的功能 2.4 简单稳定 2.5 客户端语言多 2.6 持久化 2.7 主从复制 2.8 高可用 和 分布式 2.9 单线程架构 2.9.1 引出单线程模型 2.9.2 单线程快的原因 2.10 Redis 和 MySQL 的特性对比 2.11 R…

【Day 18】Linux-DNS解析

目录 一、DNS概念 1、概念和作用 2、域名解析类型 3、 软件与服务 4、DNS核心概念 区域 记录 5、查询类型 6、分层结构 二、DNS操作 配置本机为DNS内网解析服务器 &#xff08;1&#xff09;修改主配置文件 &#xff08;2&#xff09;添加区域 正向解析区域&#xff1a; …

Python 中 OpenCV (cv2) 安装与使用介绍

Python 中 OpenCV (cv2) 安装与使用详细指南 OpenCV (Open Source Computer Vision Library) 是计算机视觉领域最流行的库之一。Python 通过 cv2 模块提供 OpenCV 的接口。 一、安装 OpenCV 方法 1&#xff1a;基础安装&#xff08;推荐&#xff09; # 安装核心包&#xff0…

微软WSUS替代方案

微软WSUS事件回顾2025年7月10日&#xff0c;微软最新确认Windows Server Update Services&#xff08;WSUS&#xff09;出现了问题&#xff0c;导致IT管理员无法正常同步和部署Windows更新。WSUS是允许管理员根据策略配置&#xff0c;将更新推送到特定计算机&#xff0c;并优化…

Minio 分布式集群安装配置

目录创建 mkdir -p /opt/minio/run && mkdir -p /etc/minio && mkdir -p /indata/disk_0/minio/datarun&#xff1a;启动脚本及二进制文件目录/etc/minio&#xff1a;配置文件目录data&#xff1a;数据存储目录下载 minio wget https://dl.min.io/server/minio…

Spring Boot + ShardingSphere 实现分库分表 + 读写分离实战

&#x1f680; Spring Boot ShardingSphere 实现分库分表 读写分离&#xff08;涵盖99%真实场景&#xff09; &#x1f3f7;️ 标签&#xff1a;ShardingSphere、分库分表、读写分离、MySQL 主从、Spring Boot 实战 分库分表 vs 读写分离 vs 主从配置与数据库高可用架构区别 …

将普通用户添加到 Docker 用户组

这样可以避免每次使用 Docker 命令时都需要 sudo。以下是具体步骤&#xff1a;1. 创建 Docker 用户组&#xff08;如果尚未存在&#xff09; 默认情况下&#xff0c;安装 Docker 时会自动创建 docker 用户组。可以通过以下命令检查&#xff1a; groupadd docker&#xff08;如果…

Scrapy(一):轻松爬取图片网站内容​

目录 一、CrawlSpider 简介​ 二、实战案例&#xff1a;图片网站爬取​ 三、代码解析&#xff1a;核心组件详解​ 类定义&#xff1a; 2.核心属性&#xff1a;​ 3.爬取规则&#xff08;Rules&#xff09;&#xff1a;​ 4.数据提取方法&#xff08;parse_item&#xff09;…

使用 systemd 的原生功能来实现 Redis 的自动监控和重启,而不是依赖额外的脚本最佳实践方案

使用 systemd 的原生功能来实现 Redis 的自动监控和重启&#xff0c;而不是依赖额外的脚本最佳实践方案方案 1&#xff1a;配置 systemd 服务文件&#xff08;推荐&#xff09;1. 检查/创建 Redis 的 systemd 服务文件2. 配置关键参数&#xff08;覆盖配置示例&#xff09;3. 重…

Eclipse 代码模板

Eclipse 代码模板 引言 Eclipse 作为一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;深受广大开发者的喜爱。在编程过程中&#xff0c;使用代码模板可以大大提高开发效率&#xff0c;减少重复劳动。本文将详细介绍 Eclipse 代码模板的配置、使用方法以及一…

输电线路防外破声光预警装置 | 防山火/防钓鱼/防施工安全警示系统

在输电网络的安全保障中&#xff0c;外力破坏是一个不容忽视的问题&#xff0c;各类隐患可能对电力系统造成严重影响。TLKS-PMG-WP 输电线路声光防外破警示装置在应对这类挑战时&#xff0c;有着独特的技术表现&#xff0c;下面从功能和技术参数两方面进行详细介绍。核心功能解…

STM32——STM32CubeMX

总&#xff1a;STM32——学习总纲 一、简介 注意&#xff0c;非逻辑代码。 可兼容不同系列的STM32Cube固件包。 STM32Cube前置知识链接&#xff1a; STM32——HAL库 不可过多依赖&#xff0c;此工具只针对STM32芯片&#xff0c;类似英飞凌芯片无法配置。主要用于参考。 二、安…

Java NIO 核心原理与秋招高频面试题解析

一、NIO 概述Java NIO&#xff08;New I/O 或 Non-blocking I/O&#xff09;是 Java 1.4 引入的一套全新 I/O API&#xff0c;位于 java.nio 包下。NIO 提供了与传统 BIO&#xff08;Blocking I/O&#xff09;完全不同的 I/O 处理方式&#xff0c;通过非阻塞模式、缓冲区&#…

vue3+element-plus,el-popover实现筛选弹窗的方法

实现一个筛选框&#xff0c;点击筛选按钮出现弹窗&#xff0c;弹窗内有选择框/输入框/单选框等等&#xff0c;底部有重置/确定两个按钮。需求&#xff1a;点击筛选外部其他位置可以关闭弹窗&#xff0c;关闭弹窗后已编辑的数据不保存&#xff0c;点击确定按钮关闭弹窗&#xff…

python每日一题 贪心算法练习

在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。给定两个整数数组 gas 和 cost &…

Python + Pika RabbitMQ集群压测完整方案

一、最近搭建了个rabbitmq集群 三个磁盘节点&#xff0c;上生产环境之前想做个压测&#xff0c;测试下稳定性&#xff0c;参考Deepseek做了如下测试方案二、核心代码实现&#xff1a; 配置文件 (config.py) import os RABBITMQ_NODES [amqp://admin:123456192.168.0.175:8101,…