unity 模型沿地表移动工具
让模型在地表移动,
目录结构
/assets/editor
using UnityEngine;using UnityEditor;using System.Collections;/// <summary>/// 模型拖动器/// 1. 地表./// 2. 地图表面./// </summary>public class ModelDragger : EditorWindow{ static readonly string INTRODUCE = "让模型沿地表移动.\n" +"沿地表:模型的高度为当前地形高度.\n" +"沿地图:模型高度为,从上面开始.第一个接触到模型的高度"; static readonly string MY_NAME = "模型拖动器"; static readonly string ALONG_TERRAIN = "沿地表拖动:"; static readonly string ALONG_MAP = "沿地图拖动:"; static readonly string ON = "开"; static readonly string OFF = "关"; static readonly string CANT_MOVE_TERRAIN = "地形,不能移动."; private bool isTerrain; private bool isMap; private Terrain curTerrain; [MenuItem("Level4/Fbx/ModelDragger")] static void Init() { ModelDragger md = EditorWindow.GetWindow<ModelDragger>(false, MY_NAME) as ModelDragger; md.curTerrain = Terrain.activeTerrain; } void OnGUI() { GUILayout.Label(INTRODUCE); //地表 EditorGUILayout.BeginHorizontal("box"); EditorGUILayout.PrefixLabel(ALONG_TERRAIN); isTerrain = GUILayout.Toggle(isTerrain, isTerrain ? OFF : ON); if (isTerrain) isMap = false; EditorGUILayout.EndHorizontal(); //地图 EditorGUILayout.BeginHorizontal("box"); EditorGUILayout.PrefixLabel(ALONG_MAP); isMap = GUILayout.Toggle(isMap, isMap ? OFF : ON); if (isMap) isTerrain = false; EditorGUILayout.EndHorizontal(); } void Update() { if (isTerrain) { DragAlongTerrain(); } else if (isMap) { DragAlongMap(); } } /// <summary> /// 模型沿地表移动 /// </summary> void DragAlongTerrain() { if (curTerrain != null) { foreach (Transform tr in Selection.transforms) { if (tr.GetComponent<Terrain>() == null) tr.position = new Vector3(tr.position.x, curTerrain.SampleHeight(tr.position), tr.position.z); else { ShowNotification(new GUIContent(CANT_MOVE_TERRAIN)); break; } } } } /// <summary> /// 模型沿地图移动. /// </summary> void DragAlongMap() { foreach (Transform tr in Selection.transforms) { if (tr.GetComponent<Terrain>() == null) FallIt(tr); else { ShowNotification(new GUIContent(CANT_MOVE_TERRAIN)); break; } } } /// <summary> /// 物体 向下掉落. /// </summary> /// <param name="tr"></param> void FallIt(Transform tr) { Vector3 origin = tr.position; origin.y += 1000; Vector3 dir = Vector3.down; RaycastHit[] hits = Physics.RaycastAll(origin, dir); Debug.DrawRay(origin,dir*100,Color.red); foreach (RaycastHit hit in hits) { if (hit.transform != tr) { tr.position = hit.point; break; } } }}