// ************************** LOD Settings ************************** // public GrassPlane AddGrassPlane() { GrassPlane newPlane = new GrassPlane(); grassPlanes.Add(newPlane); return(newPlane); }
public void Distribute(GrassPatch patch) { Transform parent = GameObject.FindGameObjectWithTag("Foliage").transform; foreach (var point in scatteredPoints) { GameObject clump = Object.Instantiate(grassObjects[Random.Range(0, grassObjects.Count - 1)]); clump.transform.position = patch.transform.TransformPoint(point); Randomize(clump); GrassPlane plane = patch.AddGrassPlane(); plane.transform = clump.transform; clump.transform.parent = parent; } }
public void AddGrassPlane() { GrassPlane newPlane = new GrassPlane(); grassPlanes.Add(newPlane); }
void Paint(SceneView sv) { if (!isPainting) { return; } if (painter.currentGroup == null) { return; } if (objectsToScatter.Count == 0) { return; } RaycastHit hitInfo = new RaycastHit(); // var ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); Ray ray = GetRay(sv); var layerMask = 1 << painter.paintLayer; //Spray if (Physics.Raycast(ray.origin, ray.direction, out hitInfo, Mathf.Infinity, layerMask)) { GameObject newObj = null; Quaternion myRot; float dist = Mathf.Infinity; GameObject objToInst = null; //Spray if (painter.currentGroup.sprayRadius > 0) { var randomCircle = Random.insideUnitCircle * painter.currentGroup.sprayRadius; var rayDirection = (hitInfo.point + new Vector3(randomCircle.x, 0, randomCircle.y)) - ray.origin; RaycastHit newHit; if (Physics.Raycast(ray.origin, rayDirection, out newHit, Mathf.Infinity, layerMask)) { hitInfo = newHit; } } //Check Distance if (painter.currentGroup.transform.childCount != 0) { foreach (var obj in myObjToInstArray)//currentGroup.transform) { var tempDist = Vector3.Distance(hitInfo.point, obj.transform.position); if (tempDist < dist) { dist = tempDist; } } } // See if we are inside of a mask zone. // Find all game objects with tag paintMask GameObject[] objectsArray; var objectMask = false; objectsArray = GameObject.FindGameObjectsWithTag("Foliage"); // Iterate through all objects and check for isInside foreach (GameObject go in objectsArray) { if (go.GetComponent <Collider>()) { if (CheckIsInside(go.GetComponent <Collider>(), hitInfo.point)) { objectMask = true; // EditorUtility.DisplayDialog("Hit a prefab painting mask!", "It looks like we hit an object with the tag paintMask", "Continue", "You have to continue"); } } } float angle; angle = Vector3.Angle(hitInfo.normal, new Vector3(0, 1, 0)); float hitHeight; hitHeight = hitInfo.point.y; // JO Added check for slop angle and altitude if (dist >= painter.currentGroup.distanceRadius && angle <= painter.currentGroup.maxSlopeVal && angle >= painter.currentGroup.minSlopeVal && hitHeight >= painter.currentGroup.minAltitudeVal && hitHeight <= painter.currentGroup.maxAltitudeVal && !objectMask) { //Biblio Method if (painter.bibSortIndex == 0) { // Random // JO Here is where you would pick an item based on the random probability of each var myRandom = Random.Range(0, objectsToScatter.Count); objToInst = objectsToScatter[myRandom]; } if (painter.bibSortIndex == 1) { objToInst = objectsToScatter[painter.soloObjectIndex]; } // Check is we're using normal placement myRot = Quaternion.identity; if (painter.currentGroup.useNormal) { myRot = Quaternion.FromToRotation(objToInst.transform.up, hitInfo.normal) * objToInst.transform.rotation; } //Create the Object // if using foilage groups if (painter.currentGroup.useFoilageGroups) { newObj = Object.Instantiate(objToInst); newObj.transform.position = hitInfo.point; //FoilageSystem.Foliage(){ } GrassPatch instPatch = newObj.GetComponent <GrassPatch>(); GrassPatch originalPatch = objToInst.GetComponent <GrassPatch>(); for (int i = 0; i < originalPatch.grassPlanes.Count; i++) { GrassPlane originalPlane = originalPatch.grassPlanes[i]; // original patch GrassPlane instPlane = instPatch.grassPlanes[i]; // instantiated patch instPlane.transform = Object.Instantiate(originalPlane.transform.gameObject).transform; instPlane.transform.parent = newObj.transform; // make position its relative position is same as original Vector3 worldPos = newObj.transform.TransformPoint(originalPlane.transform.localPosition); Vector3 localPos = newObj.transform.InverseTransformPoint(worldPos); instPlane.transform.localPosition = localPos; // make it rotate according to ground normal // instPlane.transform.rotation = myRot; RaycastHit hit = new RaycastHit(); if (Physics.Raycast(instPlane.transform.position, Vector3.down, out hit, LayerMask.NameToLayer("Ground"))) { //Quaternion rot = Quaternion.FromToRotation(instPlane.transform.up, hit.normal) * instPlane.transform.rotation; //instPlane.transform.rotation = rot; //instPlane.transform.eulerAngles = hit.normal; //instPlane.transform.position = hit.point; } instPlane.groundVerts = originalPlane.groundVerts; } myObjToInstArray.Add(newObj); } else { newObj = Object.Instantiate(objToInst); // PrefabUtility.InstantiatePrefab(objToInst); newObj.transform.position = hitInfo.point; newObj.transform.rotation = myRot; myObjToInstArray.Add(newObj); } // Update Points Array painter.currentGroup.AddScatterObject(newObj, hitInfo.point, newObj.transform.localScale, hitInfo.normal, painter.currentGroup.useNormal); // Update Position Pivot if (painter.currentGroup.transform.childCount == 0) { painter.currentGroup.transform.position = newObj.transform.position; newObj.transform.parent = painter.currentGroup.transform; } else { newObj.transform.parent = painter.currentGroup.transform; } RandomizeSolo(painter.currentGroup.myPointsList[painter.currentGroup.myPointsList.Count - 1]); // if using foilage groups if (painter.currentGroup.useFoilageGroups) { GrassPatch patch = newObj.GetComponent <GrassPatch>(); patch.Place(); } } } }
/// <summary> /// This is just a "Demo" function. /// Distributes the points across the location, based on the position /// of Generated Points. /// </summary> public void Distribute(FoilageGroup group) { if (Points == null || group == null) { Debug.Log("Points not generated or foilage groups is null"); return; } RaycastHit hitInfo; // create a parent for distributed objects GameObject parent = new GameObject(); parent.name = location.name + " -Parent"; foreach (Vector3 position in Points) { if (Physics.Raycast(position, Vector3.down, out hitInfo)) // create a ray from destinaion position in -Y direction. { // choose a random object from foilage group objects int rand = Random.Range(0, group.groupObjects.Count); GameObject originalObj = group.groupObjects[rand]; if (originalObj.GetComponent <GrassPatch>()) { GameObject newObj = Instantiate(originalObj); newObj.transform.position = hitInfo.point + new Vector3(0, 3f, 0); newObj.transform.parent = parent.transform; group.Randomize(newObj, group.foilageRules[rand]); GrassPatch instPatch = newObj.GetComponent <GrassPatch>(); GrassPatch originalPatch = originalObj.GetComponent <GrassPatch>(); for (int i = 0; i < originalPatch.grassPlanes.Count; i++) { GrassPlane originalPlane = originalPatch.grassPlanes[i]; // original patch GrassPlane instPlane = instPatch.grassPlanes[i]; // instantiated patch instPlane.transform = Instantiate(originalPlane.transform.gameObject).transform; instPlane.transform.parent = newObj.transform; // copy settings instPlane.groundVerts = originalPlane.groundVerts; // make position its relative position is same as original Vector3 worldPos = newObj.transform.TransformPoint(originalPlane.transform.localPosition); Vector3 localPos = newObj.transform.InverseTransformPoint(worldPos); instPlane.transform.localPosition = localPos; // make it rotate according to ground normal hitInfo = new RaycastHit(); if (Physics.Raycast(instPlane.transform.position, -Vector3.up * 5f, out hitInfo, LayerMask.NameToLayer("Ground"))) { if (group.foilageRules[rand].useNormal) { instPlane.transform.localEulerAngles = hitInfo.normal; } instPlane.transform.position = hitInfo.point; } } instPatch.Place(); } } } }
void DrawUI() { for (int i = 0; i < grassPatch.grassPlanes.Count; i++) { EditorGUILayout.BeginHorizontal(); grassPatch.grassPlanes[i].transform = (Transform)EditorGUILayout.ObjectField(grassPatch.grassPlanes[i].transform, typeof(Transform), true); if (GUILayout.Button("Select")) { currentSelectedObject.transform = grassPatch.grassPlanes[i].transform; currentSelectedObject.plane = grassPatch.grassPlanes[i]; currentSelectedVertex = Vector3.zero; SceneView.RepaintAll(); } if (GUILayout.Button("Remove")) { grassPatch.RemoveGrassPlane(i); currentSelectedObject = new HitObjectInfo(); } EditorGUILayout.EndHorizontal(); } if (currentSelectedObject == null || currentSelectedObject.transform == null) { return; } GrassPlane p = currentSelectedObject.plane; EditorGUILayout.Separator(); EditorGUILayout.Separator(); EditorUtils.HorizontalLine(Color.blue); EditorGUILayout.Separator(); EditorGUILayout.Separator(); EditorGUILayout.BeginHorizontal(); //if (GUILayout.Button("Add Ground Vert")) //{ // currentSelectedGroundVert = p.AddGroundVert(currentSelectedVertex); //} EditorGUILayout.EndHorizontal(); EditorGUILayout.Separator(); EditorGUILayout.Separator(); foreach (var groundVert in p.groundVerts) { EditorGUILayout.BeginHorizontal(); GUILayout.Label(groundVert.vertex.ToString()); if (GUILayout.Button("Select")) { currentSelectedVertex = groundVert.vertex; currentSelectedGroundVert = groundVert; SceneView.RepaintAll(); } ; //if (GUILayout.Button("Add")) { groundVert.influencedVerts.Add(currentSelectedVertex); SceneView.RepaintAll(); } //if (GUILayout.Button("Clear")) { groundVert.ClearInfluenced(); SceneView.RepaintAll(); } if (GUILayout.Button("Remove")) { p.RemoveGroundVert(groundVert); SceneView.RepaintAll(); break; } EditorGUILayout.EndHorizontal(); } }