public static void OnInspectorGUI(TrackBuildR _trackBuildR, int selectedPointIndex, int selectedCurveIndex) { TrackBuildRTrack _track = _trackBuildR.track; if (TrackBuildREditor._stageToolbarTexturesA == null) return; GUILayout.BeginVertical(GUILayout.Width(400)); //Track Preview Window EditorGUILayout.Space(); RenderPreview(_trackBuildR); EditorGUILayout.LabelField("Track Lap Length approx. " + (_track.trackLength / 1000).ToString("F2") + "km / " + (_track.trackLength / 1609.34f).ToString("F2") + " miles"); EditorGUILayout.LabelField("Track Polycount: "+_track.lastPolycount); int currentTrackMode = (int)_trackBuildR.mode; int currentTrackModeA = currentTrackMode < 5 ? currentTrackMode : -1; int currentTrackModeB = currentTrackMode > 4 ? currentTrackMode - 5 : -1; GUIContent[] guiContentA = new GUIContent[TrackBuildREditor.numberOfMenuOptionsA]; GUIContent[] guiContentB = new GUIContent[TrackBuildREditor.numberOfMenuOptionsB]; for (int i = 0; i < TrackBuildREditor.numberOfMenuOptionsA; i++) guiContentA[i] = new GUIContent(TrackBuildREditor._stageToolbarTexturesA[i], TrackBuildREditor.trackModeString[i]); for (int i = 0; i < TrackBuildREditor.numberOfMenuOptionsB; i++) guiContentB[i] = new GUIContent(TrackBuildREditor._stageToolbarTexturesB[i], TrackBuildREditor.trackModeString[i]); int newTrackModeA = GUILayout.Toolbar(currentTrackModeA, guiContentA, GUILayout.Width(400), GUILayout.Height(50)); int newTrackModeB = GUILayout.Toolbar(currentTrackModeB, guiContentB, GUILayout.Width(400), GUILayout.Height(50)); if (newTrackModeA != currentTrackModeA) { _trackBuildR.mode = (TrackBuildR.modes)newTrackModeA; GUI.changed = true; } if (newTrackModeB != currentTrackModeB) { _trackBuildR.mode = (TrackBuildR.modes)newTrackModeB + 5; GUI.changed = true; } if (_track.numberOfTextures == 0) EditorGUILayout.HelpBox("There are no textures defined. Track will not render until this is done", MessageType.Error); TrackBuildRPoint point = null; if (_track.realNumberOfPoints > 0) { point = _trackBuildR.track[selectedPointIndex]; } if(!_track.render) EditorGUILayout.HelpBox("Track rendering is disabled", MessageType.Warning); switch(_trackBuildR.mode) { case TrackBuildR.modes.track: EditorGUILayout.Space(); Title("Track", TrackBuildRColours.GREEN); bool trackloop = EditorGUILayout.Toggle("Is Looped", _track.loop); if(_track.loop != trackloop) { Undo.RecordObject(_track, "Toggled Loop"); _track.loop = trackloop; } EditorGUILayout.BeginHorizontal(); if(_trackBuildR.pointMode != TrackBuildR.pointModes.add) { if(GUILayout.Button("Add New Point")) _trackBuildR.pointMode = TrackBuildR.pointModes.add; } else { if(GUILayout.Button("Cancel Add New Point")) _trackBuildR.pointMode = TrackBuildR.pointModes.transform; } EditorGUI.BeginDisabledGroup(_track.realNumberOfPoints < 3); if(_trackBuildR.pointMode != TrackBuildR.pointModes.remove) { if(GUILayout.Button("Remove Point")) _trackBuildR.pointMode = TrackBuildR.pointModes.remove; } else { if(GUILayout.Button("Cancel Remove Point")) _trackBuildR.pointMode = TrackBuildR.pointModes.transform; } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); if(!_track.drawMode) { EditorGUILayout.BeginHorizontal(); if(GUILayout.Button("Layout Track Points")) { if(EditorUtility.DisplayDialog("Discard Current Track?", "Do you wish to discard the current track layout?", "Yup", "Nope")) { _track.Clear(); _track.loop = true; _track.drawMode = true; } } if(GUILayout.Button("?", GUILayout.Width(35))) { EditorUtility.DisplayDialog("Layout Track", "This allows you to click place points to define your track. It will erase the current track layout and start anew. Ideally used with a defined diagram to help you plot out the track", "Ok - got it!"); } EditorGUILayout.EndHorizontal(); } else { if(GUILayout.Button("Stop Layout Track")) { _track.loop = false; _track.drawMode = false; } EditorGUILayout.EndVertical(); return; } float meshResolution = _track.meshResolution; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Track Mesh Resolution", GUILayout.Width(140)); meshResolution = EditorGUILayout.Slider(meshResolution, 0.9f, 20.0f); EditorGUILayout.LabelField("metres", GUILayout.Width(60)); EditorGUILayout.EndHorizontal(); if(meshResolution != _track.meshResolution) { _track.SetTrackDirty(); _track.meshResolution = meshResolution; } if(_track.realNumberOfPoints == 0) { EditorGUILayout.HelpBox("There are no track points defined, add nextNormIndex track point to begin", MessageType.Warning); EditorGUILayout.EndVertical(); return; } EditorGUILayout.Space(); Title("Track Point", TrackBuildRColours.RED); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Point " + (selectedPointIndex + 1) + " selected"); if(GUILayout.Button("Goto Point")) GotoScenePoint(point.position); EditorGUILayout.EndHorizontal(); int currentMode = (int)_trackBuildR.pointMode; int newStage = GUILayout.Toolbar(currentMode, TrackBuildREditor.pointModeString); if(newStage != currentMode) { _trackBuildR.pointMode = (TrackBuildR.pointModes)newStage; GUI.changed = true; } switch(_trackBuildR.pointMode) { case TrackBuildR.pointModes.transform: Vector3 pointposition = EditorGUILayout.Vector3Field("Point Position", point.position); if(pointposition != point.position) { Undo.RecordObject(point, "Position Modified"); point.position = pointposition; } break; case TrackBuildR.pointModes.controlpoint: bool pointsplitControlPoints = EditorGUILayout.Toggle("Split Control Points", point.splitControlPoints); if(pointsplitControlPoints != point.splitControlPoints) { Undo.RecordObject(point, "Split Points Toggled"); point.splitControlPoints = pointsplitControlPoints; } Vector3 pointforwardControlPoint = EditorGUILayout.Vector3Field("Control Point Position", point.forwardControlPoint); if(pointforwardControlPoint != point.forwardControlPoint) { Undo.RecordObject(point, "Forward Control Point Changed"); point.forwardControlPoint = pointforwardControlPoint; } break; case TrackBuildR.pointModes.trackup: //nothing to show - yet... break; case TrackBuildR.pointModes.trackpoint: EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Point Crown"); float pointcrownAngle = EditorGUILayout.Slider(point.crownAngle, -45, 45); if(pointcrownAngle != point.crownAngle) { point.isDirty = true; Undo.RecordObject(point, "Crown Modified"); point.crownAngle = pointcrownAngle; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Point Width", GUILayout.Width(250)); float pointwidth = EditorGUILayout.FloatField(point.width); if(pointwidth != point.width) { point.isDirty = true; Undo.RecordObject(point, "Width Modified"); point.width = pointwidth; } EditorGUILayout.LabelField("metres", GUILayout.Width(75)); EditorGUILayout.EndHorizontal(); break; } break; case TrackBuildR.modes.boundary: EditorGUILayout.Space(); Title("Track Boundary", TrackBuildRColours.GREEN); //Track Based Boundary Options EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Split Boundary from Track"); bool trackdisconnectBoundary = EditorGUILayout.Toggle(_track.disconnectBoundary, GUILayout.Width(25)); if(trackdisconnectBoundary != _track.disconnectBoundary) { Undo.RecordObject(_track, "disconnect boundary"); _track.disconnectBoundary = trackdisconnectBoundary; GUI.changed = true; _track.ReRenderTrack(); } if(GUILayout.Button("Reset Boundary Points")) { Undo.RecordObject(_track, "reset boundary"); for(int i = 0; i < _track.numberOfPoints; i++) { _track[i].MatchBoundaryValues(); } } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Render Both Sides of Boundary"); bool renderBothSides = EditorGUILayout.Toggle(_track.renderBoundaryWallReverse, GUILayout.Width(50)); if(_track.renderBoundaryWallReverse != renderBothSides) { Undo.RecordObject(_track, "render reverse boundary"); _track.renderBoundaryWallReverse = renderBothSides; GUI.changed = true; _track.ReRenderTrack(); } EditorGUILayout.EndHorizontal(); float newTrackColliderHeight = EditorGUILayout.FloatField("Track Collider Height", _track.trackColliderWallHeight); if(newTrackColliderHeight != _track.trackColliderWallHeight) { Undo.RecordObject(_track, "trackCollider height"); _track.trackColliderWallHeight = newTrackColliderHeight; _track.ReRenderTrack(); GUI.changed = true; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Track Collider Should Have Roof"); bool newRoofCooliderValue = EditorGUILayout.Toggle(_track.includeColliderRoof, GUILayout.Width(50)); if(newRoofCooliderValue != _track.includeColliderRoof) { Undo.RecordObject(_track, "trackCollider roof"); _track.includeColliderRoof = newRoofCooliderValue; _track.ReRenderTrack(); GUI.changed = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); Title("Point Boundary", TrackBuildRColours.RED); //Selected Point Boundary Options EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Point " + (selectedPointIndex + 1) + " selected"); if(GUILayout.Button("Goto Point")) GotoScenePoint(point.position); EditorGUILayout.EndHorizontal(); int currentBoundaryMode = (int)_trackBuildR.boundaryMode; int newBoundaryMode = GUILayout.Toolbar(currentBoundaryMode, TrackBuildREditor.boundaryModeString); if(newBoundaryMode != currentBoundaryMode) { _trackBuildR.boundaryMode = (TrackBuildR.boundaryModes)newBoundaryMode; GUI.changed = true; } if(_track.realNumberOfPoints > 0) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Split Boundary Control Points"); bool pointSplitControlPoints = EditorGUILayout.Toggle(point.leftSplitControlPoints, GUILayout.Width(50)); if(point.leftSplitControlPoints != pointSplitControlPoints) { Undo.RecordObject(point, "split boundary"); point.leftSplitControlPoints = pointSplitControlPoints; point.rightSplitControlPoints = pointSplitControlPoints; GUI.changed = true; _track.SetTrackDirty(); } EditorGUILayout.EndHorizontal(); } EditorGUILayout.HelpBox("It is suggested that you disable the trackCollider bounding box when working on Track BuildR\nYou can do this by clicking on 'gizmos' above the scene view and deselecting 'Mesh Collider'", MessageType.Info); break; case TrackBuildR.modes.bumpers: EditorGUILayout.Space(); Title("Track Bumpers", TrackBuildRColours.RED); bool _tracktrackBumpers = EditorGUILayout.Toggle("Enable", _track.trackBumpers); if(_track.trackBumpers != _tracktrackBumpers) { Undo.RecordObject(_track, "bumpers"); if(_tracktrackBumpers == false) for(int i = 0; i < _track.numberOfCurves; i++) _track[i].generateBumpers = false; _track.trackBumpers = _tracktrackBumpers; } EditorGUI.BeginDisabledGroup(!_track.trackBumpers); TrackBuildRTrack.BumperModes _trackBumperMode = (TrackBuildRTrack.BumperModes)EditorGUILayout.EnumPopup("Bumper Mode", _track.bumperMode); if (_track.bumperMode != _trackBumperMode) { Undo.RecordObject(_track, "bumpers"); _track.bumperMode = _trackBumperMode; _track.SetTrackDirty(); } float bumperWidth = EditorGUILayout.Slider("Width", _track.bumperWidth, 0.1f, 2.0f); if(bumperWidth != _track.bumperWidth) { Undo.RecordObject(_track, "bumper width"); GUI.changed = true; _track.bumperWidth = bumperWidth; } float bumperHeight = EditorGUILayout.Slider("Outer Height", _track.bumperHeight, 0.01f, 0.2f); if(bumperHeight != _track.bumperHeight) { Undo.RecordObject(_track, "bumper height"); GUI.changed = true; _track.bumperHeight = bumperHeight; } float additionalBumperHeight = EditorGUILayout.Slider("Additional Height", _track.additionalBumperHeight, 0.0f, 0.2f); if (additionalBumperHeight != _track.additionalBumperHeight) { Undo.RecordObject(_track, "bumper height"); GUI.changed = true; _track.additionalBumperHeight = additionalBumperHeight; } float bumperAngleThresold = EditorGUILayout.Slider("Threshold Angle", _track.bumperAngleThresold, 0.005f, 1.5f); if(bumperAngleThresold != _track.bumperAngleThresold) { Undo.RecordObject(_track, "bumper threshold"); GUI.changed = true; _track.bumperAngleThresold = bumperAngleThresold; } if(GUI.changed)//change on mouse up { _track.ReRenderTrack(); } EditorGUI.EndDisabledGroup(); break; case TrackBuildR.modes.textures: EditorGUILayout.Space(); Title("Render Properties", TrackBuildRColours.BLUE); pointTrackSelection = GUILayout.Toolbar(pointTrackSelection, pointTrackNames); TrackBuildRPoint[] selectedCurves; EditorGUILayout.BeginHorizontal(); switch(pointTrackSelection) { default://selected point selectedCurves = new []{_track[selectedCurveIndex]};//select the single track point to modify Undo.RecordObjects(selectedCurves, "Curve Details Modified"); EditorGUILayout.LabelField("Selected Curve: " + selectedCurves[0].pointName); if(GUILayout.Button("Goto Curve")) GotoScenePoint(selectedCurves[0].center); break; case 1://track wide selectedCurves = _track.points;//select all track points to modify Undo.RecordObjects(selectedCurves, "Curve Details Modified"); break; } EditorGUILayout.EndHorizontal(); TrackBuildRPoint selectedCurve = selectedCurves[0]; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Render Curve"); bool render = EditorGUILayout.Toggle(selectedCurve.render); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Render Boundaries"); bool renderBounds = EditorGUILayout.Toggle(selectedCurve.renderBounds); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Boundary Height"); float boundaryHeight = EditorGUILayout.Slider(selectedCurve.boundaryHeight, 0, 10); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Colliders"); bool trackCollider = EditorGUILayout.Toggle(selectedCurve.trackCollider); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Side Colliders"); bool colliderSides = EditorGUILayout.Toggle(selectedCurve.colliderSides); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Track Width", GUILayout.Width(250)); float trackPointWidth = EditorGUILayout.FloatField(selectedCurve.width); EditorGUILayout.LabelField("metres", GUILayout.Width(75)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Extrude Track"); bool extrudeTrack = EditorGUILayout.Toggle(selectedCurve.extrudeTrack); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Render Track Bottom"); bool extrudeTrackBottom = EditorGUILayout.Toggle(selectedCurve.extrudeTrackBottom); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Render Curve End"); bool extrudeCurveEnd = EditorGUILayout.Toggle(selectedCurve.extrudeCurveEnd); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Extrude Length"); float extrudeLength = EditorGUILayout.Slider(selectedCurve.extrudeLength, 0.1f, 100.0f); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Extrude Bevel"); float extrudeBevel = EditorGUILayout.Slider(selectedCurve.extrudeBevel, 0, 2); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Generate Bumpers"); bool generateBumpers = EditorGUILayout.Toggle(selectedCurve.generateBumpers); EditorGUILayout.EndHorizontal(); if (selectedCurve.width != trackPointWidth) foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.width = trackPointWidth; if (selectedCurve.render != render) foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.render = render; if (selectedCurve.renderBounds != renderBounds) foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.renderBounds = renderBounds; if (selectedCurve.boundaryHeight != boundaryHeight) foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.boundaryHeight = boundaryHeight; if (selectedCurve.trackCollider != trackCollider) foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.trackCollider = trackCollider; if (selectedCurve.extrudeTrack != extrudeTrack) foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.extrudeTrack = extrudeTrack; if (selectedCurve.extrudeTrackBottom != extrudeTrackBottom) foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.extrudeTrackBottom = extrudeTrackBottom; if (selectedCurve.extrudeCurveEnd != extrudeCurveEnd) foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.extrudeCurveEnd = extrudeCurveEnd; if (selectedCurve.extrudeLength != extrudeLength) foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.extrudeLength = extrudeLength; if (selectedCurve.extrudeBevel != extrudeBevel) foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.extrudeBevel = extrudeBevel; if (selectedCurve.generateBumpers != generateBumpers) foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.generateBumpers = generateBumpers; if (selectedCurve.colliderSides != colliderSides) foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.colliderSides = colliderSides; TrackBuildRTexture[] textures = _track.GetTexturesArray(); int numberOfTextures = textures.Length; string[] textureNames = new string[numberOfTextures]; for(int t = 0; t < numberOfTextures; t++) textureNames[t] = textures[t].customName; if(numberOfTextures > 0) { int trackTextureStyleIndex = CurveTextureSelector(_track, selectedCurve.trackTextureStyleIndex, "Track Texture"); if(trackTextureStyleIndex != selectedCurve.trackTextureStyleIndex) { foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.trackTextureStyleIndex = trackTextureStyleIndex; GUI.changed = true; _track.ReRenderTrack(); } int offroadTextureStyleIndex = CurveTextureSelector(_track, selectedCurve.offroadTextureStyleIndex, "Offroad Texture"); if(offroadTextureStyleIndex != selectedCurve.offroadTextureStyleIndex) { foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.offroadTextureStyleIndex = offroadTextureStyleIndex; GUI.changed = true; _track.ReRenderTrack(); } int boundaryTextureStyleIndex = CurveTextureSelector(_track, selectedCurve.boundaryTextureStyleIndex, "Boundary Texture"); if(boundaryTextureStyleIndex != selectedCurve.boundaryTextureStyleIndex) { foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.boundaryTextureStyleIndex = boundaryTextureStyleIndex; GUI.changed = true; _track.ReRenderTrack(); } int bumperTextureStyleIndex = CurveTextureSelector(_track, selectedCurve.bumperTextureStyleIndex, "Bumper Texture"); if(bumperTextureStyleIndex != selectedCurve.bumperTextureStyleIndex) { foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.bumperTextureStyleIndex = bumperTextureStyleIndex; GUI.changed = true; _track.ReRenderTrack(); } int extrudeTextureStyleIndex = CurveTextureSelector(_track, selectedCurve.bottomTextureStyleIndex, "Track Extrude Texture"); if(extrudeTextureStyleIndex != selectedCurve.bottomTextureStyleIndex) { foreach (TrackBuildRPoint selectedCurveArray in selectedCurves) selectedCurveArray.bottomTextureStyleIndex = extrudeTextureStyleIndex; GUI.changed = true; _track.ReRenderTrack(); } } EditorGUILayout.Space(); Title("Track Texture Library", TrackBuildRColours.RED); if(GUILayout.Button("Add New")) { _track.AddTexture(); numberOfTextures++; selectedTexture = numberOfTextures - 1; } if(numberOfTextures == 0) { EditorGUILayout.HelpBox("There are no textures to show", MessageType.Info); // return; break; } if(numberOfTextures > 0) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Texture", GUILayout.Width(75)); selectedTexture = EditorGUILayout.Popup(selectedTexture, textureNames); TrackBuildRTexture trackBuildRTexture = _track.Texture(selectedTexture); if(GUILayout.Button("Remove Texture")) { _track.RemoveTexture(trackBuildRTexture); numberOfTextures--; selectedTexture = 0; trackBuildRTexture = _track.Texture(selectedTexture); return; } EditorGUILayout.EndHorizontal(); if(TextureGUI(ref trackBuildRTexture)) { _track.ReRenderTrack(); } } break; case TrackBuildR.modes.terrain: Title("Terrain", TrackBuildRColours.RED); EditorGUILayout.HelpBox("I'd love to hear feedback on this new feature.\nWhat works? What doesn't.\nLet me know!", MessageType.Info); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Terrain Mode", GUILayout.Width(90)); EditorGUI.BeginDisabledGroup(_trackBuildR.terrainMode == TrackBuildR.terrainModes.mergeTerrain); if(GUILayout.Button("Merge Terrain")) _trackBuildR.terrainMode = TrackBuildR.terrainModes.mergeTerrain; EditorGUI.EndDisabledGroup(); EditorGUI.BeginDisabledGroup(_trackBuildR.terrainMode == TrackBuildR.terrainModes.conformTrack); if(GUILayout.Button("Conform Track")) _trackBuildR.terrainMode = TrackBuildR.terrainModes.conformTrack; EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); switch(_trackBuildR.terrainMode) { case TrackBuildR.terrainModes.mergeTerrain: EditorGUILayout.BeginVertical("box"); Title("Terrain Merge", TrackBuildRColours.RED); EditorGUILayout.LabelField("Selected Terrain"); EditorGUILayout.BeginHorizontal(); _track.mergeTerrain = (Terrain)EditorGUILayout.ObjectField(_track.mergeTerrain, typeof(Terrain), true); if(GUILayout.Button("Find Terrain")) _track.mergeTerrain = GameObject.FindObjectOfType<Terrain>(); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginVertical("box"); EditorGUILayout.LabelField("Terrain Merge Width"); _track.terrainMergeWidth = EditorGUILayout.Slider(_track.terrainMergeWidth, 0, 100); EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical("box"); EditorGUILayout.LabelField("Terrain Match Accuracy"); _track.terrainAccuracy = EditorGUILayout.Slider(_track.terrainAccuracy, 0, 5); EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical("box"); EditorGUILayout.LabelField("Terrain Match Margin"); _track.terrainMergeMargin = EditorGUILayout.Slider(_track.terrainMergeMargin, 1, 5); EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical("box"); EditorGUILayout.LabelField("Terrain Merge Curve"); _track.mergeCurve = EditorGUILayout.CurveField(_track.mergeCurve, GUILayout.Height(75)); EditorGUILayout.EndVertical(); if (_track.mergeTerrain == null) EditorGUILayout.HelpBox("You have not selected a terrain in the scene", MessageType.Error); if (_track.disconnectBoundary) EditorGUILayout.HelpBox("Terrain Merge doesn't fully support tracks that have boundaries split", MessageType.Error); EditorGUI.BeginDisabledGroup(_track.mergeTerrain == null); if(GUILayout.Button("Merge Terrain", GUILayout.Height(50))) { if(_track.disconnectBoundary) { if (EditorUtility.DisplayDialog("Terrain Merge Warning", "Terrain Merge doesn't fully support tracks that have boundaries split", "Continue", "Cancel")) { Undo.RecordObject(_track.mergeTerrain.terrainData, "Merge Terrain"); TrackBuildRTerrain.MergeTerrain(_track, _track.mergeTerrain); } } else { Undo.RecordObject(_track.mergeTerrain.terrainData, "Merge Terrain"); TrackBuildRTerrain.MergeTerrain(_track, _track.mergeTerrain); } } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndVertical(); break; case TrackBuildR.terrainModes.conformTrack: EditorGUILayout.BeginVertical("box"); Title("Conform Track to Terrain", TrackBuildRColours.RED); EditorGUILayout.LabelField("Selected Terrain"); EditorGUILayout.BeginHorizontal(); _track.mergeTerrain = (Terrain)EditorGUILayout.ObjectField(_track.mergeTerrain, typeof(Terrain), true); if(GUILayout.Button("Find Terrain")) _track.mergeTerrain = GameObject.FindObjectOfType<Terrain>(); EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginVertical("box"); EditorGUILayout.LabelField("Track Conform Accuracy"); _track.conformAccuracy = EditorGUILayout.Slider(_track.conformAccuracy, 0, 25); EditorGUILayout.EndVertical(); if (_track.mergeTerrain == null) EditorGUILayout.HelpBox("You have not selected a terrain in the scene", MessageType.Error); EditorGUI.BeginDisabledGroup(_track.mergeTerrain == null); if(GUILayout.Button("Conform Track", GUILayout.Height(50))) { Undo.RecordObject(_track, "Conform Track"); TrackBuildRTerrain.ConformTrack(_track, _track.mergeTerrain); } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndVertical(); break; } break; case TrackBuildR.modes.stunt: EditorGUILayout.Space(); Title("Stunt", TrackBuildRColours.RED); if(_track.realNumberOfPoints == 0) { EditorGUILayout.HelpBox("No Track to Apply Parts to",MessageType.Error); return; } EditorGUILayout.BeginHorizontal("box"); EditorGUILayout.LabelField("Stunt Part Type"); _trackBuildR.stuntMode = (TrackBuildR.stuntModes)EditorGUILayout.EnumPopup(_trackBuildR.stuntMode, GUILayout.Width(160), GUILayout.Height(30)); EditorGUILayout.EndHorizontal(); switch(_trackBuildR.stuntMode) { case TrackBuildR.stuntModes.loop: EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Loop Radius"); _track.loopRadius = EditorGUILayout.Slider(_track.loopRadius, 10, 100); EditorGUILayout.EndHorizontal(); if(GUILayout.Button("Add Loop da Loop")) { Undo.RecordObject(_track, "Add Loop"); TrackBuildRStuntUtil.AddLoop(_track, selectedPointIndex); GUI.changed = true; } break; case TrackBuildR.stuntModes.jump: EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Jump Height Radius"); _track.jumpHeight = EditorGUILayout.Slider(_track.jumpHeight, 0, 50); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Maximum Jump Length"); _track.maxJumpLength = EditorGUILayout.Slider(_track.maxJumpLength, 1, 100); EditorGUILayout.EndHorizontal(); if (GUILayout.Button("Add Jump to Point")) { // Undo.RecordObject(_track, "Add Jump"); TrackBuildRStuntUtil.AddJump(_track, selectedPointIndex); GUI.changed = true; } break; case TrackBuildR.stuntModes.jumptwist: EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Jump Height Radius"); _track.jumpHeight = EditorGUILayout.Slider(_track.jumpHeight, 0, 50); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Maximum Jump Length"); _track.maxJumpLength = EditorGUILayout.Slider(_track.maxJumpLength, 1, 100); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Jump Twist Angle"); _track.twistAngle = EditorGUILayout.Slider(_track.twistAngle, -90, 90); EditorGUILayout.EndHorizontal(); if (GUILayout.Button("Add Jump Twist to Point")) { // Undo.RecordObject(_track, "Add Jump"); TrackBuildRStuntUtil.AddJumpTwist(_track, selectedPointIndex); GUI.changed = true; } break; // case TrackBuildR.stuntModes.twist: // // EditorGUILayout.BeginHorizontal(); // EditorGUILayout.LabelField("Twist Radius"); // _track.twistRadius = EditorGUILayout.Slider(_track.twistRadius, 0, 50); // EditorGUILayout.EndHorizontal(); // // // EditorGUILayout.BeginHorizontal(); // EditorGUILayout.LabelField("Maximum Twist Length"); // _track.maxJumpLength = EditorGUILayout.Slider(_track.maxJumpLength, 1, 100); // EditorGUILayout.EndHorizontal(); // // if(GUILayout.Button("Add Twist to Point")) // { // // Undo.RecordObject(_track, "Add Jump"); // TrackBuildRStuntUtil.AddTwist(_track, selectedPointIndex); // GUI.changed = true; // } // // break; } break; case TrackBuildR.modes.diagram: _track.CheckDiagram(); EditorGUILayout.Space(); Title("Diagram Image", TrackBuildRColours.RED); _track.showDiagram = EditorGUILayout.Toggle("Show Diagram", _track.showDiagram); _track.diagramGO.GetComponent<Renderer>().enabled = _track.showDiagram; EditorGUILayout.BeginHorizontal(); if(_track.diagramMaterial.mainTexture != null) { float height = _track.diagramMaterial.mainTexture.height * (200.0f / _track.diagramMaterial.mainTexture.width); GUILayout.Label(_track.diagramMaterial.mainTexture, GUILayout.Width(200), GUILayout.Height(height)); } EditorGUILayout.BeginVertical(); if(GUILayout.Button("Load Diagram")) { string newDiagramFilepath = EditorUtility.OpenFilePanel("Load Track Diagram", "/", ""); if(newDiagramFilepath != _track.diagramFilepath) { _track.diagramFilepath = newDiagramFilepath; WWW www = new WWW("file:///" + newDiagramFilepath); Texture2D newTexture = new Texture2D(100, 100); www.LoadImageIntoTexture(newTexture); _track.diagramMaterial.mainTexture = newTexture; _track.diagramGO.transform.localScale = new Vector3(newTexture.width, 0, newTexture.height); _track.showDiagram = true; } } if(GUILayout.Button("Clear")) { _track.diagramFilepath = ""; _track.diagramMaterial.mainTexture = null; _track.showDiagram = false; } GUILayout.Space(20); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Diagram Scale", GUILayout.Width(100)); float newScale = EditorGUILayout.FloatField(_track.scale, GUILayout.Width(40)); if(_track.scale != newScale) { _track.scale = newScale; UpdateDiagram(_track); } EditorGUILayout.LabelField("metres", GUILayout.Width(50)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if(_track.assignedPoints == 0) { if(GUILayout.Button("Draw Scale")) { _track.assignedPoints = 1; } if(GUILayout.Button("?", GUILayout.Width(25))) { EditorUtility.DisplayDialog("Draw Scale", "Once you load a diagram, use this to define the start and end of the diagram scale (I do hope your diagram has a scale...)", "ok"); } } else { if(GUILayout.Button("Cancel Draw Scale")) { _track.assignedPoints = 0; } } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); EditorGUILayout.LabelField(_track.diagramFilepath); break; case TrackBuildR.modes.options: EditorGUILayout.Space(); Title("Generation Options", TrackBuildRColours.RED); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Render Track"); _track.render = EditorGUILayout.Toggle(_track.render, GUILayout.Width(15)); EditorGUILayout.EndHorizontal(); //Toggle showing the wireframe when we have selected the model. EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUILayout.LabelField("Show Wireframe"); _track.showWireframe = EditorGUILayout.Toggle(_track.showWireframe, GUILayout.Width(15)); EditorGUILayout.EndHorizontal(); //Lightmap rendering EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUI.BeginDisabledGroup(_trackBuildR.lightmapGenerated); if(GUILayout.Button("Build Lightmap UVs", GUILayout.Height(38))) { Undo.RecordObject(_trackBuildR, "Build Lightmap UVs"); _trackBuildR.GenerateSecondaryUVSet(); GUI.changed = false; } EditorGUI.EndDisabledGroup(); if(!_trackBuildR.lightmapGenerated) EditorGUILayout.HelpBox("The model doesn't have lightmap UVs", MessageType.Warning); EditorGUILayout.EndHorizontal(); //Mesh Optimisation EditorGUILayout.BeginHorizontal(GUILayout.Width(400)); EditorGUI.BeginDisabledGroup(_trackBuildR.optimised); if(GUILayout.Button("Optimise Mesh For Runtime", GUILayout.Height(38))) { Undo.RecordObject(_trackBuildR, "Optimise Meshes"); _trackBuildR.OptimseMeshes(); GUI.changed = false; } EditorGUI.EndDisabledGroup(); if(!_trackBuildR.optimised) EditorGUILayout.HelpBox("The model is currently fully optimised for runtime", MessageType.Warning); EditorGUILayout.EndHorizontal(); if(GUILayout.Button("Force Full Rebuild of Track")) _trackBuildR.ForceFullRecalculation(); break; case TrackBuildR.modes.export: TrackBuildRExport.InspectorGUI(_trackBuildR); break; } GUILayout.EndVertical(); }
private static void ExportModel(TrackBuildR track) { GameObject baseObject = new GameObject(track.exportFilename); baseObject.transform.position = CURRENT_TRANSFORM.position; baseObject.transform.rotation = CURRENT_TRANSFORM.rotation; EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.0f); track.ForceFullRecalculation(); EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.1f); try { TrackBuildRTrack trackData = track.track; //check overwrites... string newDirectory = ROOT_FOLDER + track.exportFilename; if (!CreateFolder(newDirectory)) { EditorUtility.ClearProgressBar(); return; } EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.15f); int numberOfCurves = trackData.numberOfCurves; int numberOfDynMeshes = 9; float exportProgress = 0.75f / (numberOfCurves * numberOfDynMeshes); ExportMaterial[] exportMaterials = new ExportMaterial[1]; ExportMaterial exportTexture = new ExportMaterial(); TrackBuildRTexture[] textures = trackData.GetTexturesArray(); int textureCount = textures.Length; Material[] materials = new Material[textureCount]; for (int t = 0; t < textureCount; t++) { TrackBuildRTexture texture = textures[t]; if (!texture.isSubstance && !texture.isUSer) { string materialPath = string.Format("{0}{1}/{2}.mat", ROOT_FOLDER, track.exportFilename, texture.customName); if (File.Exists(materialPath)) { Material mat = (Material)AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)); EditorUtility.CopySerialized(texture.material, mat); AssetDatabase.SaveAssets(); materials[t] = mat; continue; } Material tempMat = Object.Instantiate(texture.material); AssetDatabase.CreateAsset(tempMat, materialPath); materials[t] = (Material)AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)); } else { materials[t] = texture.isUSer ? texture.userMaterial : texture.proceduralMaterial; } } string[] dynNames = { "track", "bumper", "boundary", "bottom", "offroad", "trackCollider" }; string[] colliderNames = { "track collider", "wall collider", "offroad collider", "bumper collider" }; for (int c = 0; c < numberOfCurves; c++) { TrackBuildRPoint curve = trackData[c]; DynamicMesh[] dynMeshes = new DynamicMesh[numberOfDynMeshes]; dynMeshes[0] = curve.dynamicTrackMesh; dynMeshes[1] = curve.dynamicBumperMesh; dynMeshes[2] = curve.dynamicBoundaryMesh; dynMeshes[3] = curve.dynamicBottomMesh; dynMeshes[4] = curve.dynamicOffroadMesh; dynMeshes[5] = curve.dynamicColliderMesh1; //track surface dynMeshes[6] = curve.dynamicColliderMesh2; //walls and roof dynMeshes[7] = curve.dynamicColliderMesh3; //track bottom and offroad dynMeshes[8] = curve.dynamicColliderMesh4; //bumpers int[] textureIndeices = { curve.trackTextureStyleIndex, curve.bumperTextureStyleIndex, curve.boundaryTextureStyleIndex, curve.bottomTextureStyleIndex, curve.offroadTextureStyleIndex, 0 }; PhysicMaterial[] physicMaterials = { trackData.Texture(curve.trackTextureStyleIndex).physicMaterial, trackData.Texture(curve.boundaryTextureStyleIndex).physicMaterial, trackData.Texture(curve.offroadTextureStyleIndex).physicMaterial, trackData.Texture(curve.bumperTextureStyleIndex).physicMaterial }; for (int d = 0; d < numberOfDynMeshes; d++) { int textureIndex = Mathf.Clamp(d, 0, 5); if (EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "Exporting Track Curve " + c + " " + dynNames[textureIndex], 0.15f + exportProgress * (c * numberOfDynMeshes + d))) { EditorUtility.ClearProgressBar(); return; } DynamicMesh exportDynMesh = dynMeshes[d]; // if(track.includeTangents || exportDynMesh.isEmpty) // exportDynMesh.Build();//rebuild with tangents TrackBuildRTexture texture = trackData.Texture(textureIndeices[textureIndex]); exportTexture.name = texture.customName; exportTexture.material = texture.material; exportTexture.generated = false; exportTexture.filepath = texture.filePath; exportMaterials[0] = exportTexture; Material mat = materials[textureIndeices[textureIndex]]; int meshCount = exportDynMesh.meshCount; Mesh[] meshes = exportDynMesh.meshes; for (int i = 0; i < meshCount; i++) { Mesh exportMesh = meshes[i]; MeshUtility.Optimize(exportMesh); string filenameSuffix = trackModelName(dynNames[textureIndex], c, (meshCount > 1) ? i : -1); // "trackCurve" + c + ((meshCount > 1) ? "_" + i.ToString() : ""); if (d > 4) //colliders { filenameSuffix = string.Format("{0}_{1}", filenameSuffix, (d % 5)); } string filename = track.exportFilename + filenameSuffix; Export(filename, ROOT_FOLDER + track.exportFilename + "/", track, exportMesh, exportMaterials); if (track.createPrefabOnExport) { AssetDatabase.Refresh();//ensure the database is up to date... string modelFilePath = ROOT_FOLDER + track.exportFilename + "/" + filename + FILE_EXTENTION; if (d < numberOfDynMeshes - 4) { GameObject newModel = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadMainAssetAtPath(modelFilePath)); newModel.name = filename; newModel.transform.parent = baseObject.transform; newModel.transform.localPosition = Vector3.zero; newModel.transform.localRotation = Quaternion.identity; MeshRenderer[] renders = newModel.GetComponentsInChildren <MeshRenderer>(); foreach (MeshRenderer rend in renders) { rend.material = mat; } } else { int colliderIndex = d - (numberOfDynMeshes - 4); GameObject colliderObject = new GameObject(colliderNames[colliderIndex]); MeshCollider collider = colliderObject.AddComponent <MeshCollider>(); collider.sharedMesh = (Mesh)AssetDatabase.LoadAssetAtPath(modelFilePath, typeof(Mesh)); collider.material = physicMaterials[colliderIndex]; colliderObject.transform.parent = baseObject.transform; colliderObject.transform.localPosition = Vector3.zero; colliderObject.transform.localRotation = Quaternion.identity; } } } } } if (track.createPrefabOnExport) { string prefabPath = ROOT_FOLDER + track.exportFilename + "/" + track.exportFilename + ".prefab"; Object prefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)); if (prefab == null) { prefab = PrefabUtility.CreateEmptyPrefab(prefabPath); } PrefabUtility.ReplacePrefab(baseObject, prefab, ReplacePrefabOptions.ConnectToPrefab); } EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.70f); AssetDatabase.Refresh();//ensure the database is up to date... } catch (System.Exception e) { Debug.LogError("Track BuildR Export Error: " + e); EditorUtility.ClearProgressBar(); AssetDatabase.Refresh();//ensure the database is up to date... } Object.DestroyImmediate(baseObject); EditorUtility.ClearProgressBar(); EditorUtility.UnloadUnusedAssetsImmediate(); AssetDatabase.Refresh(); }
private static void ExportModel(TrackBuildR track) { GameObject baseObject = new GameObject(track.exportFilename); baseObject.transform.position = CURRENT_TRANSFORM.position; baseObject.transform.rotation = CURRENT_TRANSFORM.rotation; EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.0f); track.ForceFullRecalculation(); EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.1f); try { TrackBuildRTrack trackData = track.track; //check overwrites... string newDirectory = ROOT_FOLDER + track.exportFilename; if (!CreateFolder(newDirectory)) { EditorUtility.ClearProgressBar(); return; } EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.15f); int numberOfCurves = trackData.numberOfCurves; float exportProgress = 0.75f / (numberOfCurves * 6.0f); ExportMaterial[] exportMaterials = new ExportMaterial[1]; ExportMaterial exportTexture = new ExportMaterial(); string[] dynNames = new [] { "track", "bumper", "boundary", "bottom", "offread", "trackCollider" }; for (int c = 0; c < numberOfCurves; c++) { TrackBuildRPoint curve = trackData[c]; int numberOfDynMeshes = 6; DynamicMeshGenericMultiMaterialMesh[] dynMeshes = new DynamicMeshGenericMultiMaterialMesh[6]; dynMeshes[0] = curve.dynamicTrackMesh; dynMeshes[1] = curve.dynamicBumperMesh; dynMeshes[2] = curve.dynamicBoundaryMesh; dynMeshes[3] = curve.dynamicBottomMesh; dynMeshes[4] = curve.dynamicOffroadMesh; dynMeshes[5] = curve.dynamicColliderMesh; int[] textureIndeices = new int[] { curve.trackTextureStyleIndex, curve.bumperTextureStyleIndex, curve.boundaryTextureStyleIndex, curve.bottomTextureStyleIndex, curve.offroadTextureStyleIndex, 0 }; for (int d = 0; d < numberOfDynMeshes; d++) { if (EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "Exporting Track Curve " + c + " " + dynNames[d], 0.15f + exportProgress * (c * 6 + d))) { EditorUtility.ClearProgressBar(); return; } DynamicMeshGenericMultiMaterialMesh exportDynMesh = dynMeshes[d]; if (track.includeTangents || exportDynMesh.isEmpty) { exportDynMesh.Build(track.includeTangents);//rebuild with tangents } TrackBuildRTexture texture = trackData.Texture(textureIndeices[d]); exportTexture.name = texture.customName; exportTexture.material = texture.material; exportTexture.generated = false; exportTexture.filepath = texture.filePath; exportMaterials[0] = exportTexture; int meshCount = exportDynMesh.meshCount; for (int i = 0; i < meshCount; i++) { Mesh exportMesh = exportDynMesh[i].mesh; MeshUtility.Optimize(exportMesh); string filenameSuffix = trackModelName(dynNames[d], c, (meshCount > 1) ? i : -1);// "trackCurve" + c + ((meshCount > 1) ? "_" + i.ToString() : ""); string filename = track.exportFilename + filenameSuffix; Export(filename, ROOT_FOLDER + track.exportFilename + "/", track, exportMesh, exportMaterials); if (track.createPrefabOnExport) { AssetDatabase.Refresh();//ensure the database is up to date... string modelFilePath = ROOT_FOLDER + track.exportFilename + "/" + filename + FILE_EXTENTION; if (d < numberOfDynMeshes - 1) { GameObject newModel = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadMainAssetAtPath(modelFilePath)); newModel.name = filename; newModel.transform.parent = baseObject.transform; newModel.transform.localPosition = Vector3.zero; newModel.transform.localRotation = Quaternion.identity; } else { GameObject colliderObject = new GameObject("trackCollider"); colliderObject.AddComponent <MeshCollider>().sharedMesh = (Mesh)AssetDatabase.LoadAssetAtPath(modelFilePath, typeof(Mesh)); colliderObject.transform.parent = baseObject.transform; colliderObject.transform.localPosition = Vector3.zero; colliderObject.transform.localRotation = Quaternion.identity; } } } } } if (track.createPrefabOnExport) { string prefabPath = ROOT_FOLDER + track.exportFilename + "/" + track.exportFilename + ".prefab"; Object prefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)); if (prefab == null) { prefab = PrefabUtility.CreateEmptyPrefab(prefabPath); } PrefabUtility.ReplacePrefab(baseObject, prefab, ReplacePrefabOptions.ConnectToPrefab); } EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.70f); AssetDatabase.Refresh();//ensure the database is up to date... } catch (System.Exception e) { Debug.LogError("BuildR Export Error: " + e); EditorUtility.ClearProgressBar(); } Object.DestroyImmediate(baseObject); EditorUtility.ClearProgressBar(); EditorUtility.UnloadUnusedAssets(); AssetDatabase.Refresh(); }
void OnSceneGUI() { if (_track.drawMode) { DrawTrack(); return; } if (SceneView.focusedWindow != null) { SceneView.focusedWindow.wantsMouseMove = false; } Vector3 position = _trackBuildR.transform.position; Camera sceneCamera = Camera.current; _handleSize = HandleUtility.GetHandleSize(_trackBuildR.transform.position) * 0.1f; int realNumberOfPoints = _track.realNumberOfPoints; Ray mouseRay = Camera.current.ScreenPointToRay(new Vector3(Event.current.mousePosition.x, Screen.height - Event.current.mousePosition.y - 30, 0)); Quaternion mouseLookDirection = Quaternion.LookRotation(-mouseRay.direction); int numberOfCurves = _track.numberOfCurves; switch (_trackBuildR.mode) { case TrackBuildR.modes.track: Handles.color = TrackBuildRColours.GREEN; switch (_trackBuildR.pointMode) { case TrackBuildR.pointModes.add: if (SceneView.focusedWindow != null) { SceneView.focusedWindow.wantsMouseMove = true; } if (Event.current.type == EventType.MouseMove) { Repaint(); } Handles.color = TrackBuildRColours.GREY; for (int i = 0; i < _track.realNumberOfPoints; i++) { Vector3 pointPos = _track[i].worldPosition; float handleSize = HandleUtility.GetHandleSize(pointPos); Handles.DotCap(0, pointPos, Quaternion.identity, handleSize * 0.05f); } Handles.color = TrackBuildRColours.GREEN; float mousePercentage = NearestmMousePercentage(); // _track.GetNearestPoint(mousePlanePoint); Vector3 mouseTrackPoint = _track.GetTrackPosition(mousePercentage) + position; Handles.Label(mouseTrackPoint, "Add New Track Point"); float newPointHandleSize = HandleUtility.GetHandleSize(mouseTrackPoint) * HANDLE_SCALE; if (Handles.Button(mouseTrackPoint, mouseLookDirection, newPointHandleSize, newPointHandleSize, Handles.DotCap)) { int newPointIndex = _track.GetLastPointIndex(mousePercentage); TrackBuildRPoint newPoint = _track.InsertPoint(newPointIndex + 1); newPoint.worldPosition = mouseTrackPoint; newPoint.width = _track.GetTrackWidth(mousePercentage); newPoint.crownAngle = _track.GetTrackCrownAngle(mousePercentage); selectedPoint = newPointIndex + 1; GUI.changed = true; _trackBuildR.pointMode = TrackBuildR.pointModes.transform; } break; case TrackBuildR.pointModes.remove: if (SceneView.focusedWindow != null) { SceneView.focusedWindow.wantsMouseMove = true; } Handles.color = TrackBuildRColours.RED; for (int i = 0; i < realNumberOfPoints; i++) { TrackBuildRPoint point = _track[i]; float pointHandleSize = HandleUtility.GetHandleSize(point.worldPosition) * HANDLE_SCALE; Handles.Label(point.worldPosition, "Remove Track Point"); if (Handles.Button(point.worldPosition, mouseLookDirection, pointHandleSize, pointHandleSize, Handles.DotCap)) { _track.RemovePoint(point); GUI.changed = true; _trackBuildR.pointMode = TrackBuildR.pointModes.transform; } } break; default: SceneGUIPointBased(); break; } //draw track outline for (int i = 0; i < numberOfCurves; i++) { TrackBuildRPoint curve = _track[i]; if (curve == null) { continue; } int curvePoints = curve.storedPointSize; float dotPA = Vector3.Dot(sceneCamera.transform.forward, curve.worldPosition - sceneCamera.transform.position); float dotPB = Vector3.Dot(sceneCamera.transform.forward, curve.nextPoint.worldPosition - sceneCamera.transform.position); if (dotPA < 0 && dotPB < 0) { continue; } float curveDistance = Vector3.Distance(sceneCamera.transform.position, curve.center); int pointJump = Mathf.Max((int)(curveDistance / 20.0f), 1); Color trackOutline = curve.render ? TrackBuildRColours.GREEN : TrackBuildRColours.RED; Color trackOutlineA = trackOutline; trackOutlineA.a = 0.5f; for (int p = pointJump; p < curvePoints; p += pointJump) { int indexA = p - pointJump; int indexB = p; if (p + pointJump > curvePoints - 1) { indexB = curvePoints - 1; } Handles.color = trackOutlineA; Handles.DrawLine(curve.sampledPoints[indexA] + position, curve.sampledPoints[indexB] + position); Handles.color = trackOutline; Vector3 trackCrossWidth = curve.sampledTrackCrosses[indexA] * (curve.sampledWidths[indexA] * 0.5f); Handles.DrawLine(curve.sampledPoints[indexA] + trackCrossWidth + position, curve.sampledPoints[indexB] + trackCrossWidth + position); Handles.DrawLine(curve.sampledPoints[indexA] - trackCrossWidth + position, curve.sampledPoints[indexB] - trackCrossWidth + position); } } break; case TrackBuildR.modes.boundary: //draw boundary outline for (int i = 0; i < numberOfCurves; i++) { TrackBuildRPoint curve = _track[i]; int curvePoints = curve.storedPointSize; float dotPA = Vector3.Dot(sceneCamera.transform.forward, curve.worldPosition - sceneCamera.transform.position); float dotPB = Vector3.Dot(sceneCamera.transform.forward, curve.nextPoint.worldPosition - sceneCamera.transform.position); if (dotPA < 0 && dotPB < 0) { continue; } float curveDistance = Vector3.Distance(sceneCamera.transform.position, curve.center); int pointJump = Mathf.Max((int)(curveDistance / 20.0f), 1); for (int p = pointJump; p < curvePoints; p += pointJump) { int indexA = p - pointJump; int indexB = p; if (p + pointJump > curvePoints - 1) { indexB = curvePoints - 1; } if (_track.disconnectBoundary) { Handles.color = TrackBuildRColours.BLUE; Handles.DrawLine(curve.sampledLeftBoundaryPoints[indexA] + position, curve.sampledLeftBoundaryPoints[indexB] + position); Handles.color = TrackBuildRColours.RED; Handles.DrawLine(curve.sampledRightBoundaryPoints[indexA] + position, curve.sampledRightBoundaryPoints[indexB] + position); } else { Vector3 trackCrossWidth = curve.sampledTrackCrosses[indexA] * (curve.sampledWidths[indexA] * 0.5f); Handles.color = TrackBuildRColours.BLUE; Handles.DrawLine(curve.sampledPoints[indexA] + trackCrossWidth + position, curve.sampledPoints[indexB] + trackCrossWidth + position); Handles.color = TrackBuildRColours.RED; Handles.DrawLine(curve.sampledPoints[indexA] - trackCrossWidth + position, curve.sampledPoints[indexB] - trackCrossWidth + position); } } } SceneGUIPointBased(); break; case TrackBuildR.modes.textures: for (int i = 0; i < numberOfCurves; i++) { TrackBuildRPoint thisCurve = _track[i]; float pointHandleSize = HandleUtility.GetHandleSize(thisCurve.center) * HANDLE_SCALE; Handles.color = (i == selectedCurveIndex) ? TrackBuildRColours.RED : TrackBuildRColours.BLUE; if (Handles.Button(thisCurve.center, Quaternion.identity, pointHandleSize, pointHandleSize, Handles.DotCap)) { selectedCurveIndex = i; GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; GUI.changed = true; } } Handles.color = TrackBuildRColours.RED; TrackBuildRPoint selectedCurve = _track[selectedCurveIndex]; int numberOfSelectedCurvePoints = selectedCurve.storedPointSize; for (int i = 0; i < numberOfSelectedCurvePoints - 1; i++) { Vector3 leftPointA = selectedCurve.sampledLeftBoundaryPoints[i]; Vector3 leftPointB = selectedCurve.sampledLeftBoundaryPoints[i + 1]; Vector3 rightPointA = selectedCurve.sampledRightBoundaryPoints[i]; Vector3 rightPointB = selectedCurve.sampledRightBoundaryPoints[i + 1]; Handles.DrawLine(leftPointA, leftPointB); Handles.DrawLine(rightPointA, rightPointB); if (i == 0) { Handles.DrawLine(leftPointA, rightPointA); } if (i == numberOfSelectedCurvePoints - 2) { Handles.DrawLine(leftPointB, rightPointB); } } break; case TrackBuildR.modes.terrain: //nothing break; case TrackBuildR.modes.stunt: SceneGUIPointBased(); TrackBuildRPoint atPoint = _track[selectedPoint]; TrackBuildRPoint lastPoint = _track.GetPoint(selectedPoint - 1); TrackBuildRPoint nextPoint = _track.GetPoint(selectedPoint + 1); float trackWidth; Vector3 startCross; Vector3 p0, p1, p2, p3, p4, p5, p6, p7; switch (_trackBuildR.stuntMode) { case TrackBuildR.stuntModes.loop: atPoint = _track[selectedPoint]; trackWidth = atPoint.width; float loopRadius = _track.loopRadius; Vector3 loopPosition = atPoint.worldPosition; Vector3 trackDirection = atPoint.trackDirection.normalized; Vector3 trackup = atPoint.trackUpQ * Vector3.forward; Vector3 trackCross = atPoint.trackCross; Vector3 loopCentreHeight = loopRadius * trackup; Quaternion loopAngle = Quaternion.FromToRotation(Vector3.right, trackDirection); for (float i = 0; i < 0.99f; i += 0.01f) { float radA = Mathf.PI * 2 * (i + 0.5f); float radB = Mathf.PI * 2 * (i + 0.51f); Vector3 pointLoopPositionA = loopAngle * ((new Vector3(Mathf.Sin(radA), Mathf.Cos(radA), 0)) * loopRadius); Vector3 pointLoopPositionB = loopAngle * ((new Vector3(Mathf.Sin(radB), Mathf.Cos(radB), 0)) * loopRadius); Vector3 lateral = Vector3.Lerp((trackCross * trackWidth * -0.6f), (trackCross * trackWidth * 0.6f), i); Vector3 pointPositionA = (pointLoopPositionA) + lateral + loopPosition + loopCentreHeight; Vector3 pointPositionB = (pointLoopPositionB) + lateral + loopPosition + loopCentreHeight; Handles.DrawLine(pointPositionA, pointPositionB); } break; case TrackBuildR.stuntModes.jump: atPoint = _track[selectedPoint]; lastPoint = _track.GetPoint(selectedPoint - 1); nextPoint = _track.GetPoint(selectedPoint + 1); float trackPartDistance = lastPoint.arcLength + atPoint.arcLength; float jumpDistance = Mathf.Min(trackPartDistance * 0.333f, _track.maxJumpLength); Vector3 jumpDirection = atPoint.trackDirection; Vector3 jumpMiddle = atPoint.worldPosition; startCross = atPoint.trackCross; trackWidth = atPoint.width * 0.5f; Quaternion trackUp = atPoint.trackUpQ; Vector3 jumpHeight = trackUp * (Vector3.forward * _track.jumpHeight); Vector3 jumpStartPosition = jumpMiddle - jumpDirection * (jumpDistance * 0.33f); Vector3 jumpEndPosition = jumpMiddle + jumpDirection * (jumpDistance * 0.33f); p0 = lastPoint.worldPosition + trackWidth * startCross; p1 = lastPoint.worldPosition - trackWidth * startCross; p2 = jumpStartPosition + trackWidth * startCross + jumpHeight; p3 = jumpStartPosition - trackWidth * startCross + jumpHeight; p4 = jumpEndPosition + trackWidth * startCross + jumpHeight; p5 = jumpEndPosition - trackWidth * startCross + jumpHeight; p6 = nextPoint.worldPosition + trackWidth * startCross; p7 = nextPoint.worldPosition - trackWidth * startCross; Handles.DrawLine(p0, p2); Handles.DrawLine(p1, p3); Handles.DrawLine(p0, p1); Handles.DrawLine(p2, p3); Handles.DrawLine(p2, p2 - jumpHeight); Handles.DrawLine(p3, p3 - jumpHeight); Handles.DrawLine(p0, p2 - jumpHeight); Handles.DrawLine(p1, p3 - jumpHeight); Handles.DrawLine(p4, p6); Handles.DrawLine(p5, p7); Handles.DrawLine(p4, p5); Handles.DrawLine(p6, p7); Handles.DrawLine(p4, p4 - jumpHeight); Handles.DrawLine(p5, p5 - jumpHeight); Handles.DrawLine(p6, p4 - jumpHeight); Handles.DrawLine(p7, p5 - jumpHeight); break; // case TrackBuildR.stuntModes.twist: // // atPoint = _track[selectedPoint]; // lastPoint = _track.GetPoint(selectedPoint - 1); // // float twistDistance = Mathf.Min((lastPoint.arcLength + atPoint.arcLength) * 0.333f, _track.maxJumpLength); // // Vector3 twistDirection = atPoint.trackDirection; // Vector3 twistMiddle = atPoint.worldPosition; // Vector3 twistUp = atPoint.trackUp; // float twistRadius = _track.twistRadius; // Vector3 twistStartPosition = twistMiddle - twistDirection * (twistDistance * 0.33f); // Vector3 twistEndPosition = twistMiddle + twistDirection * (twistDistance * 0.33f); // Vector3 twistCentreHeight = twistUp * twistRadius; // Quaternion twistAngle = Quaternion.LookRotation(twistDirection, twistUp); // for(float i = 0; i < 0.99f; i += 0.01f ) // { // float radA = Mathf.PI * 2 * (i+0.5f); // float radB = Mathf.PI * 2 * (i+0.51f); // Vector3 pointLoopPositionA = twistAngle * ((new Vector3(Mathf.Sin(radA), Mathf.Cos(radA), 0)) * twistRadius); // Vector3 pointLoopPositionB = twistAngle * ((new Vector3(Mathf.Sin(radB), Mathf.Cos(radB), 0)) * twistRadius); // float smoothI = i * i * (3.0f - 2.0f * i); // Vector3 lateral = Vector3.Lerp(twistStartPosition, twistEndPosition, i + (i-smoothI)); // Vector3 pointPositionA = (pointLoopPositionA) + lateral + twistCentreHeight; // Vector3 pointPositionB = (pointLoopPositionB) + lateral + twistCentreHeight; // Handles.DrawLine(pointPositionA, pointPositionB); // } // // break; case TrackBuildR.stuntModes.jumptwist: atPoint = _track[selectedPoint]; lastPoint = _track.GetPoint(selectedPoint - 1); nextPoint = _track.GetPoint(selectedPoint + 1); float trackTPartDistance = lastPoint.arcLength + atPoint.arcLength; float jumpTDistance = Mathf.Min(trackTPartDistance * 0.333f, _track.maxJumpLength); trackWidth = atPoint.width * 0.5f; startCross = atPoint.trackCross; Vector3 jumpTDirection = atPoint.trackDirection; Vector3 jumpTMiddle = atPoint.worldPosition; Quaternion atPointUpQ = atPoint.trackUpQ; Quaternion trackUpJump = Quaternion.AngleAxis(_track.twistAngle, -jumpTDirection); Vector3 trackCrossExit = trackUpJump * startCross; Vector3 trackCrossEntry = Quaternion.Inverse(trackUpJump) * startCross; Vector3 jumpLateral = startCross * _track.twistAngle / 33.3f; Vector3 jumpTHeight = atPointUpQ * (Vector3.forward * _track.jumpHeight); Vector3 jumpTStartPosition = jumpTMiddle - jumpTDirection * (jumpTDistance * 0.33f) + jumpTHeight - jumpLateral; Vector3 jumpTEndPosition = jumpTMiddle + jumpTDirection * (jumpTDistance * 0.33f) + jumpTHeight + jumpLateral; p0 = lastPoint.worldPosition + trackWidth * startCross; p1 = lastPoint.worldPosition - trackWidth * startCross; p2 = jumpTStartPosition + trackWidth * trackCrossExit; p3 = jumpTStartPosition - trackWidth * trackCrossExit; p4 = jumpTEndPosition + trackWidth * trackCrossEntry; p5 = jumpTEndPosition - trackWidth * trackCrossEntry; p6 = nextPoint.worldPosition + trackWidth * startCross; p7 = nextPoint.worldPosition - trackWidth * startCross; Handles.DrawLine(p0, p2); Handles.DrawLine(p1, p3); Handles.DrawLine(p0, p1); Handles.DrawLine(p2, p3); // Handles.DrawLine(p2, p2 - jumpTHeight); // Handles.DrawLine(p3, p3 - jumpTHeight); // Handles.DrawLine(p0, p2 - jumpTHeight); // Handles.DrawLine(p1, p3 - jumpTHeight); Handles.DrawLine(p4, p6); Handles.DrawLine(p5, p7); Handles.DrawLine(p4, p5); Handles.DrawLine(p6, p7); // Handles.DrawLine(p4, p4 - jumpTHeight); // Handles.DrawLine(p5, p5 - jumpTHeight); // Handles.DrawLine(p6, p4 - jumpTHeight); // Handles.DrawLine(p7, p5 - jumpTHeight); break; } break; case TrackBuildR.modes.diagram: if (SceneView.focusedWindow != null) { SceneView.focusedWindow.wantsMouseMove = true; } if (!_track.showDiagram) { break; } Plane diagramPlane = new Plane(Vector3.up, position); float diagramDistance; float crossSize = _handleSize * 10; switch (_trackBuildR.track.assignedPoints) { case 0: //display the diagram scale points Vector3 diagramPointA = _track.scalePointA; Vector3 diagramPointB = _track.scalePointB; if (diagramPointA != Vector3.zero || diagramPointB != Vector3.zero) { Handles.color = TrackBuildRColours.BLUE; Handles.DrawLine(diagramPointA, diagramPointA + Vector3.left * crossSize); Handles.DrawLine(diagramPointA, diagramPointA + Vector3.right * crossSize); Handles.DrawLine(diagramPointA, diagramPointA + Vector3.forward * crossSize); Handles.DrawLine(diagramPointA, diagramPointA + Vector3.back * crossSize); Handles.color = TrackBuildRColours.GREEN; Handles.DrawLine(diagramPointB, diagramPointB + Vector3.left * crossSize); Handles.DrawLine(diagramPointB, diagramPointB + Vector3.right * crossSize); Handles.DrawLine(diagramPointB, diagramPointB + Vector3.forward * crossSize); Handles.DrawLine(diagramPointB, diagramPointB + Vector3.back * crossSize); Handles.color = TrackBuildRColours.RED; Handles.DrawLine(diagramPointA, diagramPointB); } break; case 1: //place the first of two scale points to define the diagram scale size Ray diagramRay = Camera.current.ScreenPointToRay(new Vector3(Event.current.mousePosition.x, Screen.height - Event.current.mousePosition.y - 30, 0)); if (diagramPlane.Raycast(diagramRay, out diagramDistance)) { Vector3 diagramPlanePoint = diagramRay.GetPoint(diagramDistance); Handles.color = TrackBuildRColours.BLUE; Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.left * crossSize); Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.right * crossSize); Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.forward * crossSize); Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.back * crossSize); Handles.color = new Color(0, 0, 0, 0); if (Handles.Button(diagramPlanePoint, Quaternion.identity, crossSize, crossSize, Handles.DotCap)) { _track.scalePointA = diagramPlanePoint; _track.assignedPoints = 2; } } break; case 2: //place the second of two scale points to define the diagram scale Vector3 diagramPoint1 = _track.scalePointA; Handles.color = TrackBuildRColours.BLUE; Handles.DrawLine(diagramPoint1, diagramPoint1 + Vector3.left * crossSize); Handles.DrawLine(diagramPoint1, diagramPoint1 + Vector3.right * crossSize); Handles.DrawLine(diagramPoint1, diagramPoint1 + Vector3.forward * crossSize); Handles.DrawLine(diagramPoint1, diagramPoint1 + Vector3.back * crossSize); Ray diagramRayB = Camera.current.ScreenPointToRay(new Vector3(Event.current.mousePosition.x, Screen.height - Event.current.mousePosition.y - 30, 0)); if (diagramPlane.Raycast(diagramRayB, out diagramDistance)) { Vector3 diagramPlanePoint = diagramRayB.GetPoint(diagramDistance); Handles.color = TrackBuildRColours.RED; Handles.DrawLine(diagramPlanePoint, diagramPoint1); Handles.color = TrackBuildRColours.GREEN; Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.left * crossSize); Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.right * crossSize); Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.forward * crossSize); Handles.DrawLine(diagramPlanePoint, diagramPlanePoint + Vector3.back * crossSize); Handles.color = new Color(0, 0, 0, 0); if (Handles.Button(diagramPlanePoint, Quaternion.identity, crossSize, crossSize, Handles.DotCap)) { _track.scalePointB = diagramPlanePoint; _track.assignedPoints = 0; //wUpdateDiagram(); } } break; } break; } if (Event.current.type == EventType.ValidateCommand) { switch (Event.current.commandName) { case "UndoRedoPerformed": // Debug.Log("UndoRedoPerformed"); _trackBuildR.ForceFullRecalculation(); GUI.changed = true; return; } } if (GUI.changed) { UpdateGui(); } }
private static void ExportModel(TrackBuildR track) { GameObject baseObject = new GameObject(track.exportFilename); baseObject.transform.position = CURRENT_TRANSFORM.position; baseObject.transform.rotation = CURRENT_TRANSFORM.rotation; EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.0f); track.ForceFullRecalculation(); EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.1f); try { TrackBuildRTrack trackData = track.track; //check overwrites... string newDirectory = ROOT_FOLDER + track.exportFilename; if(!CreateFolder(newDirectory)) { EditorUtility.ClearProgressBar(); return; } EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.15f); int numberOfCurves = trackData.numberOfCurves; int numberOfDynMeshes = 9; float exportProgress = 0.75f / (numberOfCurves * numberOfDynMeshes); ExportMaterial[] exportMaterials = new ExportMaterial[1]; ExportMaterial exportTexture = new ExportMaterial(); TrackBuildRTexture[] textures = trackData.GetTexturesArray(); int textureCount = textures.Length; Material[] materials = new Material[textureCount]; for (int t = 0; t < textureCount; t++) { TrackBuildRTexture texture = textures[t]; if (!texture.isSubstance && !texture.isUSer) { string materialPath = string.Format("{0}{1}/{2}.mat", ROOT_FOLDER, track.exportFilename, texture.customName); if(File.Exists(materialPath)) { Material mat = (Material)AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)); EditorUtility.CopySerialized(texture.material, mat); AssetDatabase.SaveAssets(); materials[t] = mat; continue; } Material tempMat = Object.Instantiate(texture.material); AssetDatabase.CreateAsset(tempMat, materialPath); materials[t] = (Material)AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)); } else { materials[t] = texture.isUSer ? texture.userMaterial : texture.proceduralMaterial; } } string[] dynNames = {"track","bumper","boundary","bottom","offroad","trackCollider"}; string[] colliderNames = { "track collider", "wall collider", "offroad collider", "bumper collider" }; for (int c = 0; c < numberOfCurves; c++) { TrackBuildRPoint curve = trackData[c]; DynamicMesh[] dynMeshes = new DynamicMesh[numberOfDynMeshes]; dynMeshes[0] = curve.dynamicTrackMesh; dynMeshes[1] = curve.dynamicBumperMesh; dynMeshes[2] = curve.dynamicBoundaryMesh; dynMeshes[3] = curve.dynamicBottomMesh; dynMeshes[4] = curve.dynamicOffroadMesh; dynMeshes[5] = curve.dynamicColliderMesh1;//track surface dynMeshes[6] = curve.dynamicColliderMesh2;//walls and roof dynMeshes[7] = curve.dynamicColliderMesh3;//track bottom and offroad dynMeshes[8] = curve.dynamicColliderMesh4;//bumpers int[] textureIndeices = { curve.trackTextureStyleIndex ,curve.bumperTextureStyleIndex, curve.boundaryTextureStyleIndex, curve.bottomTextureStyleIndex, curve.offroadTextureStyleIndex, 0}; PhysicMaterial[] physicMaterials = { trackData.Texture(curve.trackTextureStyleIndex).physicMaterial, trackData.Texture(curve.boundaryTextureStyleIndex).physicMaterial, trackData.Texture(curve.offroadTextureStyleIndex).physicMaterial, trackData.Texture(curve.bumperTextureStyleIndex).physicMaterial }; for (int d = 0; d < numberOfDynMeshes; d++) { int textureIndex = Mathf.Clamp(d, 0, 5); if (EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "Exporting Track Curve " + c + " " + dynNames[textureIndex], 0.15f + exportProgress * (c * numberOfDynMeshes + d))) { EditorUtility.ClearProgressBar(); return; } DynamicMesh exportDynMesh = dynMeshes[d]; // if(track.includeTangents || exportDynMesh.isEmpty) // exportDynMesh.Build();//rebuild with tangents TrackBuildRTexture texture = trackData.Texture(textureIndeices[textureIndex]); exportTexture.name = texture.customName; exportTexture.material = texture.material; exportTexture.generated = false; exportTexture.filepath = texture.filePath; exportMaterials[0] = exportTexture; Material mat = materials[textureIndeices[textureIndex]]; int meshCount = exportDynMesh.meshCount; Mesh[] meshes = exportDynMesh.meshes; for (int i = 0; i < meshCount; i++) { Mesh exportMesh = meshes[i]; MeshUtility.Optimize(exportMesh); string filenameSuffix = trackModelName(dynNames[textureIndex], c, (meshCount > 1) ? i : -1);// "trackCurve" + c + ((meshCount > 1) ? "_" + i.ToString() : ""); if(d > 4)//colliders filenameSuffix = string.Format("{0}_{1}", filenameSuffix, (d % 5)); string filename = track.exportFilename + filenameSuffix; Export(filename, ROOT_FOLDER + track.exportFilename + "/", track, exportMesh, exportMaterials); if(track.createPrefabOnExport) { AssetDatabase.Refresh();//ensure the database is up to date... string modelFilePath = ROOT_FOLDER + track.exportFilename + "/" + filename + FILE_EXTENTION; if(d < numberOfDynMeshes - 4) { GameObject newModel = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadMainAssetAtPath(modelFilePath)); newModel.name = filename; newModel.transform.parent = baseObject.transform; newModel.transform.localPosition = Vector3.zero; newModel.transform.localRotation = Quaternion.identity; MeshRenderer[] renders = newModel.GetComponentsInChildren<MeshRenderer>(); foreach(MeshRenderer rend in renders) rend.material = mat; } else { int colliderIndex = d - (numberOfDynMeshes - 4); GameObject colliderObject = new GameObject(colliderNames[colliderIndex]); MeshCollider collider = colliderObject.AddComponent<MeshCollider>(); collider.sharedMesh = (Mesh)AssetDatabase.LoadAssetAtPath(modelFilePath, typeof(Mesh)); collider.material = physicMaterials[colliderIndex]; colliderObject.transform.parent = baseObject.transform; colliderObject.transform.localPosition = Vector3.zero; colliderObject.transform.localRotation = Quaternion.identity; } } } } } if(track.createPrefabOnExport) { string prefabPath = ROOT_FOLDER + track.exportFilename + "/" + track.exportFilename + ".prefab"; Object prefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)); if(prefab == null) prefab = PrefabUtility.CreateEmptyPrefab(prefabPath); PrefabUtility.ReplacePrefab(baseObject, prefab, ReplacePrefabOptions.ConnectToPrefab); } EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.70f); AssetDatabase.Refresh();//ensure the database is up to date... } catch(System.Exception e) { Debug.LogError("Track BuildR Export Error: "+e); EditorUtility.ClearProgressBar(); AssetDatabase.Refresh();//ensure the database is up to date... } Object.DestroyImmediate(baseObject); EditorUtility.ClearProgressBar(); EditorUtility.UnloadUnusedAssetsImmediate(); AssetDatabase.Refresh(); }