/// <summary> /// Raycast against all hazards /// </summary> /// <param name="ray"></param> /// <param name="distance"></param> /// <returns></returns> public static HazardHit RaycastHazards(Ray ray, float distance = 10) { ray.direction = new Vector3(ray.direction.x, 0, ray.direction.z).normalized; HazardHit hit = new HazardHit(); bool hitted = false; bool insideOOB = false; List <HazardBase> hazards = Hazards; for (int i = 0; i < hazards.Count; ++i) { HazardHit temp = new HazardHit(); if (hazards[i].Raycast(ray, temp, distance)) { switch (temp.type) { case HazardBase.Type.Out_of_Bounds: insideOOB = true; break; default: hitted = true; hit = temp; break; } } } if (hitted) { return(hit); } else { if (insideOOB) { return(hit); } else { Layer layer = CourseBase.GetLayer(Utility.GetName(HazardBase.Type.Out_of_Bounds), CourseBase.HazardLayers); if (Hazards.Find(x => x.Layer == layer)) { hit.type = HazardBase.Type.Out_of_Bounds; hit.InstanceID = Hazards.Find(x => x.Layer == layer).Info.InstanceID; return(hit); } else { hit.type = HazardBase.Type.Out_of_Bounds; return(hit); } } } }
/// <summary> /// Creates spline /// </summary> /// <param name="info"></param> /// <returns></returns> public static SplineBase CreateSpline(SplineBase.SplineInfo info) { SplineBase spline = CreateSpline(info.points.ToVector3(), CourseBase.GetLayer(info.layerName, SplineLayers), (SplineBase.SplineInfo.Flags)info.flags, info.InstanceID); spline.Info.pin = info.pin; spline.UpdateLine(); splines.Add(spline); spline.LineChanged(); return(spline); }
/// <summary> /// Raycast the hazard for intesections /// </summary> /// <param name="ray"></param> /// <param name="hit"></param> /// <param name="distance"></param> /// <returns></returns> public bool Raycast(Ray ray, CourseBase.HazardHit hit, float distance = 10) { Vector3[] points = Lines.Points; Color[] colors = Lines.Colors; if (!InBounds(ray.origin)) { return(false); } if (!ray.origin.IsInside(points)) { return(false); } distance = Mathf.Max(distance, Lines.Points.LineLength()); Vector3 startPosition = ray.origin + ray.direction.normalized * distance; bool crossed = false; for (int i = 0; i < points.Length; ++i) { if (MathUtility.IsSegmentSegment(ray.origin.ToVector2(), startPosition.ToVector2(), points.GetAt(i - 1).ToVector2(), points.GetAt(i).ToVector2())) { string name = CourseBase.HazardLayers.Find(h => h.hazardColor == colors.GetAt(i - 1)).name; if (CourseBase.IsHazard(name)) { Vector3 point = MathUtility.LineLine(ray.origin.ToVector2(), startPosition.ToVector2(), points.GetAt(i - 1).ToVector2(), points.GetAt(i).ToVector2()).Value; point = new Vector3(point.x, CourseBase.MeshHeight(point.x, point.y), point.y); if (hit.point == Vector3.zero || (point - ray.origin).magnitude < (hit.point - ray.origin).magnitude) { hit.type = CourseBase.HazardType(name); hit.point = point; hit.pointIndex = i; hit.InstanceID = Info.InstanceID; crossed = true; } } } } return(crossed); }
Vector3 GetNormal(Vector3 middle, Vector3 left, Vector3 right, Vector2 position, bool blendNormals = false) { Vector3 n = Vector3.zero; Vector3 nl = Vector3.zero; Vector3 nr = Vector3.zero; Vector3 nm = CourseBase.TerrainNormal(middle); if (right != Vector3.zero) { nr = (middle - right).normalized; nr = Quaternion.AngleAxis(90, Vector3.Cross(new Vector3(nr.x, 0, nr.z).normalized, Vector3.up)) * nr; } if (left != Vector3.zero) { nl = (left - middle).normalized; nl = Quaternion.AngleAxis(90, Vector3.Cross(new Vector3(nl.x, 0, nl.z).normalized, Vector3.up)) * nl; } if (right != Vector3.zero && left != Vector3.zero) { /* * if (blendNormals) n = new Vector3(nr.x + nl.x, nr.y * nl.y, nr.z + nl.z); * else n = Vector3.Lerp(nl, nr, 0.5f); * * n = new Vector3(n.x + nm.x, n.y * nm.y, n.z + nm.z); * n.Normalize(); */ n = Vector3.Lerp(nl, nr, 0.5f); n = Vector3.Lerp(nm, n, 0.75f); } else { n = CourseBase.TerrainNormal(middle); } return(n); }
public override void UpdateMaterial() { base.UpdateMaterial(); for (int i = 0; i < posts.Count; ++i) { MonoBehaviour.DestroyImmediate(posts[i]); posts.RemoveAt(i); i = -1; continue; } Vector3[] path = Lines.Lines; Color[] colors = Lines.LinesColors; for (int i = 1; i < path.Length; ++i) { if (colors[i - 1] != colors[i]) { Layer layer1 = CourseBase.HazardLayers.Find(h => h.hazardColor == colors[i - 1]); if (layer1 == null) { continue; } GameObject prefab1 = layer1.HazardPost; if (prefab1 == null) { continue; } GameObject post1 = MonoBehaviour.Instantiate(prefab1) as GameObject; post1.transform.parent = transform; post1.transform.localPosition = path[i - 1]; post1.transform.forward = path[i].Direction(path[i - 1]); post1.transform.localRotation *= Quaternion.Euler(-90, 0, 0); posts.Add(post1); Layer layer2 = CourseBase.HazardLayers.Find(h => h.hazardColor == colors[i]); if (layer2 == null) { continue; } GameObject prefab2 = layer2.HazardPost; if (prefab2 == null) { continue; } GameObject post2 = MonoBehaviour.Instantiate(prefab2) as GameObject; post2.transform.parent = transform; post2.transform.localPosition = path[i]; post2.transform.forward = path[i].Direction(path[i - 1]); post2.transform.localRotation *= Quaternion.Euler(-90, 0, 0); posts.Add(post2); } } float length = Lines.Lines.LineLength(); for (float x = 0; x < length - Layer.metersPerOnePost; x += Layer.metersPerOnePost) { Vector3 position = Position(x); position.y = CourseBase.MeshHeight(position.x, position.z); if (posts.Find(h => (h.transform.position - position).magnitude < Layer.metersPerOnePost * 0.75f)) { continue; } Vector3 nextPosition = Position(x + 0.1f); nextPosition.y = CourseBase.MeshHeight(nextPosition.x, nextPosition.z); Color color = Color(x); Layer layer = CourseBase.HazardLayers.Find(h => h.hazardColor == color); if (layer == null) { continue; } GameObject prefab = CourseBase.HazardLayers.Find(h => h.hazardColor == color).HazardPost; if (prefab == null) { continue; } GameObject post = MonoBehaviour.Instantiate(prefab) as GameObject; post.transform.parent = transform; post.transform.localPosition = position; post.transform.forward = nextPosition.Direction2D(position); post.transform.localRotation *= Quaternion.Euler(-90, 0, 0); posts.Add(post); } }
/// <summary> /// Retrieve target position based on the hole information /// </summary> /// <param name="holeIndex"></param> /// <param name="nodes"></param> /// <param name="pinPosition"></param> /// <param name="shotPosition"></param> /// <param name="teePosition"></param> /// <returns></returns> public Vector3 TargetPosition(int holeIndex, List <Node> nodes, Vector3 pinPosition, Vector3 shotPosition, Vector3 teePosition) { switch (target) { case Target.Probe: return(probe.position.ToVector3()); case Target.Tee: if (CourseBase.IsHoleEnabled(holeIndex)) { if (teePosition != Vector3.zero) { return(teePosition); } else { return(CourseBase.Holes[holeIndex].tees[0].Position); } } break; case Target.Pin: if (CourseBase.IsHoleEnabled(holeIndex)) { if (pinPosition != Vector3.zero) { return(pinPosition); } else { return(CourseBase.Holes[holeIndex].pins[0].Position); } } break; case Target.Shot: if (CourseBase.IsHoleEnabled(holeIndex)) { if (shotPosition != Vector3.zero) { return(shotPosition); } else if (CourseBase.Holes[holeIndex].shots.Count > 0) { return(CourseBase.Holes[holeIndex].shots[0].Position); } } break; case Target.GameObject: if (cameraTarget == null) { return(position.ToVector3()); } else { return(cameraTarget.position); } case Target.Next: if (this == nodes[nodes.Count - 1]) { return(position.ToVector3()); } return(GetNext(nodes).position.ToVector3()); case Target.Previous: if (this == nodes[0]) { return(position.ToVector3()); } return(GetPrevious(nodes).position.ToVector3()); case Target.NextProbe: if (this == nodes[nodes.Count - 1]) { return(position.ToVector3()); } return(GetNext(nodes).TargetPosition(holeIndex, nodes, pinPosition, shotPosition, teePosition)); case Target.PreviousProbe: if (this == nodes[0]) { return(position.ToVector3()); } return(GetPrevious(nodes).TargetPosition(holeIndex, nodes, pinPosition, shotPosition, teePosition)); default: return(Vector3.zero); } return(Vector3.zero); }
void OnDisable() { self = null; ForceUpdate(); }
void OnEnable() { self = this; ForceUpdate(); }
Vector3 GetPosition(Vector2 position, float offset) { float height = CourseBase.TerrainHeight(position.x, position.y); return(new Vector3(position.x, height + offset, position.y)); }
/// <summary> /// Update the lines /// </summary> /// <param name="spline"></param> public void UpdateLines(SplineBase spline) { if (spline.IsSquare) { List <Vector3> temp = editorPoints.ToList(); temp.Add(temp[0]); editorLinesPoints = temp.ToArray(); } else { editorLinesPoints = editorPoints.CatmullRom(spline.Layer.pointsPerEdge, true).ToArray(); } if (spline.IsHazard) { editorLinesColors = new Color[editorLinesPoints.Length]; string[] colorNames = spline.Info.colorNames; editorColors = new Color[colorNames.Length]; for (int i = 0; i < colorNames.Length; ++i) { editorColors[i] = CourseBase.GetLayer(colorNames[i], CourseBase.HazardLayers).hazardColor; } int step = (int)(editorLinesPoints.Length / editorPoints.Length); int index = 0; int counter = 0; for (int i = 0; i < editorLinesPoints.Length; ++i) { try { editorLinesColors[i] = editorColors[index]; counter++; if (counter == step) { counter = 0; if (index != editorPoints.Length - 1) { index++; } } } catch (Exception e) { Debug.Log(editorColors.Length + "[" + index + "]"); Debug.LogException(e); } } } editorBoxesPoints = new Vector3[editorPoints.Length * 9]; for (int i = 0; i < editorPoints.Length; ++i) { editorBoxesPoints[i * 9 + 0].Set(editorPoints[i].x - Utility.squareHalf, editorPoints[i].y, editorPoints[i].z - Utility.squareHalf); editorBoxesPoints[i * 9 + 1].Set(editorPoints[i].x + Utility.squareHalf, editorPoints[i].y, editorPoints[i].z - Utility.squareHalf); editorBoxesPoints[i * 9 + 2].Set(editorPoints[i].x - Utility.squareHalf, editorPoints[i].y, editorPoints[i].z - Utility.squareHalf); editorBoxesPoints[i * 9 + 3].Set(editorPoints[i].x - Utility.squareHalf, editorPoints[i].y, editorPoints[i].z + Utility.squareHalf); editorBoxesPoints[i * 9 + 4].Set(editorPoints[i].x - Utility.squareHalf, editorPoints[i].y, editorPoints[i].z + Utility.squareHalf); editorBoxesPoints[i * 9 + 5].Set(editorPoints[i].x + Utility.squareHalf, editorPoints[i].y, editorPoints[i].z + Utility.squareHalf); editorBoxesPoints[i * 9 + 6].Set(editorPoints[i].x + Utility.squareHalf, editorPoints[i].y, editorPoints[i].z - Utility.squareHalf); editorBoxesPoints[i * 9 + 7].Set(editorPoints[i].x + Utility.squareHalf, editorPoints[i].y, editorPoints[i].z + Utility.squareHalf); editorBoxesPoints[i * 9 + 8].Set(0, float.PositiveInfinity, 0); } editorMin = editorLinesPoints[0]; editorMax = editorLinesPoints[0]; for (int i = 0; i < editorLinesPoints.Length; ++i) { if (editorLinesPoints[i].x < editorMin.x) { editorMin.x = editorLinesPoints[i].x; } if (editorLinesPoints[i].y < editorMin.y) { editorMin.y = editorLinesPoints[i].y; } if (editorLinesPoints[i].z < editorMin.z) { editorMin.z = editorLinesPoints[i].z; } if (editorLinesPoints[i].x > editorMax.x) { editorMax.x = editorLinesPoints[i].x; } if (editorLinesPoints[i].y > editorMax.y) { editorMax.y = editorLinesPoints[i].y; } if (editorLinesPoints[i].z > editorMax.z) { editorMax.z = editorLinesPoints[i].z; } } editorMin /= 1.01f; editorMax *= 1.01f; }