I'm generating points and mesh on run-time, the problem is, the generated mesh vertices appeared in the wrong position, even if I pass on the point's global position.
the mesh generating part is made in MakeMeshData();
I tired calculating with all my points with position instead of localPosition, as well as commenting out the parenting, still the same result .
https://imgur.com/a/YAlpXfh
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NPG03_Corridor : MonoBehaviour
{
public Transform centerPoint;
public Transform startPoint;
public Transform endPoint;
public enum CORRIDORTYPE
{
LinearBezierCurves,
QuadraticBezierCurves,
CubicBezierCurve
}
public CORRIDORTYPE corridorType;
public List<Transform> centerLinePoints = new List<Transform>();
public List<Transform> corridorAllPoint = new List<Transform>();
List<Transform> rightPoints = new List<Transform>();
List<Transform> leftPoints = new List<Transform>();
public List<GameObject> listOfCorridorFloor = new List<GameObject>();
public Vector3[] corridorVertices;
public int[] corridorTrangle;
public float StartEndDistanceFromCenter = 15;
public float minStartEndDistanceFromCenter = 10;
public float maxStartEndDistanceFromCenter = 20;
public int controlDirection = 1;
public float minControlDistanceFromCenter = 10;
public float maxControlDistanceFromCenter = 30;
public int numberOfLinePoint = 15;
public int numberOfMesh;
public Vector3[] testVec = new Vector3[3];
int[] textInt = new int[3];
private void Start()
{
BasiceSetup();
PointsSetups();
MakeMeshData();
}
private void BasiceSetup()
{
numberOfMesh = (numberOfLinePoint - 1);
GameObject pointHolderObject = new GameObject();
GameObject centerPointObject = new GameObject();
GameObject startPointObject = new GameObject();
GameObject endPostionObject = new GameObject();
centerPoint = centerPointObject.transform;
startPoint = startPointObject.transform;
endPoint = endPostionObject.transform;
pointHolderObject.name = "Point Holder";
centerPointObject.name = "Center Point";
startPointObject.name = "Start Point";
endPostionObject.name = "End Point";
pointHolderObject.transform.parent = transform;
centerPointObject.transform.parent = pointHolderObject.transform;
startPointObject.transform.parent = pointHolderObject.transform;
endPostionObject.transform.parent = pointHolderObject.transform;
pointHolderObject.transform.localPosition = Vector3.zero;
pointHolderObject.transform.localRotation = Quaternion.Euler(Vector3.zero);
centerPointObject.transform.localPosition = Vector3.zero;
centerPointObject.transform.localRotation = Quaternion.Euler(Vector3.zero);
startPointObject.transform.localPosition = Vector3.zero;
startPointObject.transform.localRotation = Quaternion.Euler(new Vector3(0, 180, 0));
endPostionObject.transform.localPosition = Vector3.zero;
endPostionObject.transform.localRotation = Quaternion.Euler(Vector3.zero);
Vector3 newStartExitPostion = Vector3.forward * (Random.Range(minStartEndDistanceFromCenter, maxStartEndDistanceFromCenter));
startPointObject.transform.localPosition = -1 * newStartExitPostion;
endPostionObject.transform.localPosition = newStartExitPostion;
NPG01_ModulePoint centerPointScript = centerPointObject.AddComponent<NPG01_ModulePoint>();
NPG01_ModulePoint startPointScript = startPointObject.AddComponent<NPG01_ModulePoint>();
NPG01_ModulePoint endPointScript = endPostionObject.AddComponent<NPG01_ModulePoint>();
centerPointScript.updatePoint(NPG01_ModulePoint.POINTSTATE.CENTER);
startPointScript.updatePoint(NPG01_ModulePoint.POINTSTATE.CONNECTION);
endPointScript.updatePoint(NPG01_ModulePoint.POINTSTATE.CONNECTION);
}
private void PointsSetups()
{
GameObject curveHolder = new GameObject();
curveHolder.transform.parent = transform;
curveHolder.name = "Curve Holder";
curveHolder.transform.localPosition = Vector3.zero;
curveHolder.transform.localRotation = Quaternion.Euler(Vector3.zero);
switch (corridorType)
{
case CORRIDORTYPE.LinearBezierCurves:
for (int i = 0; i < numberOfLinePoint; i++)
{
GameObject point = new GameObject();
point.name = "Curve Point " + i.ToString();
point.transform.parent = curveHolder.transform;
point.transform.localPosition = Vector3.zero;
point.transform.localRotation = Quaternion.Euler(Vector3.zero);
NPG01_ModulePoint pointScript = point.AddComponent<NPG01_ModulePoint>();
pointScript.updatePoint(NPG01_ModulePoint.POINTSTATE.BEZIERCURVES);
centerLinePoints.Add(point.transform);
}
for (int i = 0; i < numberOfLinePoint; i++)
{
float t = (float)i / ((float)numberOfLinePoint - 1);
centerLinePoints[i].localPosition = LinearBezierCurves(startPoint.localPosition, endPoint.localPosition, t);
GameObject rightPoint = new GameObject();
GameObject leftPoint = new GameObject();
rightPoint.transform.parent = curveHolder.transform;
rightPoint.name = "Right " + i;
rightPoint.transform.localRotation = Quaternion.Euler(Vector3.zero);
rightPoint.transform.localPosition = centerLinePoints[i].localPosition + (Vector3.right * 3);
NPG01_ModulePoint rightPointScript = rightPoint.AddComponent<NPG01_ModulePoint>();
rightPointScript.updatePoint(NPG01_ModulePoint.POINTSTATE.BEZIERCURVES);
leftPoint.transform.parent = curveHolder.transform;
leftPoint.name = "Left " + i;
leftPoint.transform.localRotation = Quaternion.Euler(Vector3.zero);
leftPoint.transform.localPosition = centerLinePoints[i].localPosition + (-Vector3.right * 3);
NPG01_ModulePoint leftPointScript = leftPoint.AddComponent<NPG01_ModulePoint>();
leftPointScript.updatePoint(NPG01_ModulePoint.POINTSTATE.BEZIERCURVES);
rightPoints.Add(rightPoint.transform);
leftPoints.Add(leftPoint.transform);
}
for (int i = 0; i < numberOfLinePoint; i++)
{
corridorAllPoint.Add(centerLinePoints[i]);
corridorAllPoint.Add(leftPoints[i]);
corridorAllPoint.Add(rightPoints[i]);
}
break;
case CORRIDORTYPE.QuadraticBezierCurves:
int controlPointDirction = Random.Range(0, 9);
if (controlPointDirction % 2 == 0)
{
controlDirection = 1;
}
else
{
controlDirection = -1;
}
GameObject controlPointObject = new GameObject();
controlPointObject.name = "Control Point";
controlPointObject.transform.parent = curveHolder.transform;
controlPointObject.transform.localPosition = Vector3.right * (20 * controlDirection);
controlPointObject.transform.localPosition = new Vector3(controlPointObject.transform.localPosition.x,
controlPointObject.transform.localPosition.y,
0);
NPG01_ModulePoint controlPointScript = controlPointObject.AddComponent<NPG01_ModulePoint>();
controlPointScript.updatePoint(NPG01_ModulePoint.POINTSTATE.BEZIERCONTROLE);
for (int i = 0; i < numberOfLinePoint; i++)
{
GameObject point = new GameObject();
point.name = "Curve Point " + i.ToString();
point.transform.parent = curveHolder.transform;
point.transform.position = Vector3.zero;
point.transform.localPosition = Vector3.zero;
point.transform.localRotation = Quaternion.Euler(Vector3.zero);
centerLinePoints.Add(point.transform);
NPG01_ModulePoint pointScript = point.AddComponent<NPG01_ModulePoint>();
pointScript.updatePoint(NPG01_ModulePoint.POINTSTATE.BEZIERCURVES);
}
for (int i = 0; i < numberOfLinePoint; i++)
{
float t = (float)i / ((float)numberOfLinePoint - 1);
centerLinePoints[i].localPosition = QuadraticBezierCurves(startPoint.localPosition, endPoint.localPosition, controlPointObject.transform.localPosition, t);
GameObject rightPoint = new GameObject();
GameObject leftPoint = new GameObject();
rightPoint.transform.parent = curveHolder.transform;
rightPoint.name = "Right " + i;
rightPoint.transform.localPosition = centerLinePoints[i].localPosition + (Vector3.right * 3);
NPG01_ModulePoint rightPointScript = rightPoint.AddComponent<NPG01_ModulePoint>();
rightPointScript.updatePoint(NPG01_ModulePoint.POINTSTATE.BEZIERCURVES);
leftPoint.transform.parent = curveHolder.transform;
leftPoint.name = "Left " + i;
leftPoint.transform.position = Vector3.zero;
leftPoint.transform.localPosition = Vector3.zero;
leftPoint.transform.localPosition = centerLinePoints[i].localPosition + (-Vector3.right * 3);
NPG01_ModulePoint leftPointScript = leftPoint.AddComponent<NPG01_ModulePoint>();
leftPointScript.updatePoint(NPG01_ModulePoint.POINTSTATE.BEZIERCURVES);
}
for (int i = 0; i < numberOfLinePoint; i++)
{
corridorAllPoint.Add(centerLinePoints[i]);
corridorAllPoint.Add(leftPoints[i]);
corridorAllPoint.Add(rightPoints[i]);
}
break;
case CORRIDORTYPE.CubicBezierCurve:
break;
}
}
private void MakeMeshData()
{
//mr = GetComponent<MeshRenderer>();
//mf = GetComponent<MeshFilter>();
GameObject meshHolder = new GameObject();
meshHolder.name = "Mesh Holder";
meshHolder.transform.parent = transform;
meshHolder.transform.localPosition = Vector3.zero;
meshHolder.transform.localRotation = Quaternion.Euler(Vector3.zero);
for (int i = 0; i < numberOfLinePoint - 1; i++)
{
GameObject leftFloorPanel = new GameObject();
GameObject rightFloorPanel = new GameObject();
leftFloorPanel.name = "Left Floor " + i.ToString();
rightFloorPanel.name = "Right Floor " + i.ToString();
leftFloorPanel.transform.parent = meshHolder.transform;
leftFloorPanel.transform.position = Vector3.zero;
leftFloorPanel.transform.localPosition = Vector3.zero;
leftFloorPanel.transform.localRotation = Quaternion.Euler(Vector3.zero);
Vector3 leftFloorPanelPostion = centerLinePoints[i].localPosition;
leftFloorPanelPostion.x = (leftPoints[i].localPosition.x + centerLinePoints[i].localPosition.x) / 2;
leftFloorPanelPostion.z = (centerLinePoints[i + 1].localPosition.z + centerLinePoints[i].localPosition.z) / 2;
leftFloorPanel.transform.localPosition = leftFloorPanelPostion;
rightFloorPanel.transform.parent = meshHolder.transform;
rightFloorPanel.transform.localPosition = Vector3.zero;
rightFloorPanel.transform.localRotation = Quaternion.Euler(Vector3.zero);
Vector3 rightFloorPanelPostion = centerLinePoints[i].localPosition;
rightFloorPanelPostion.x = (rightPoints[i].localPosition.x + centerLinePoints[i].localPosition.x) / 2;
rightFloorPanelPostion.z = (centerLinePoints[i + 1].localPosition.z + centerLinePoints[i].localPosition.z) / 2;
rightFloorPanel.transform.localPosition = rightFloorPanelPostion;
listOfCorridorFloor.Add(leftFloorPanel);
listOfCorridorFloor.Add(rightFloorPanel);
// Debug.Log(leftFloorPanel.transform.position + " " + leftFloorPanel.transform.localPosition);
}
corridorVertices = new Vector3[listOfCorridorFloor.Count * 3];
corridorTrangle = new int[listOfCorridorFloor.Count * 3];
//listOfCorridorFloor[0].transform.parent = null;
//centerLinePoints[0].transform.parent = null;
//leftPoints[0].transform.parent = null;
//leftPoints[1].transform.parent = null;
testVec[0] = centerLinePoints[0].transform.position;
testVec[1] = leftPoints[0].transform.position;
testVec[2] = leftPoints[1].transform.position;
//testVec[3] = leftPoints[1].transform.position;
//testVec[4] = centerLinePoints[1].position;
//testVec[5] = centerLinePoints[0].position;
textInt[0] = 0;
textInt[1] = 1;
textInt[2] = 2;
//textInt[3] = 3;
//textInt[4] = 4;
//textInt[5] = 5;
listOfCorridorFloor[0].AddComponent<MeshFilter>();
listOfCorridorFloor[0].AddComponent<MeshRenderer>();
}
private void Update()
{
Mesh testmesh = listOfCorridorFloor[0].GetComponent<MeshFilter>().mesh;
testVec[0] = centerLinePoints[0].transform.position;
testVec[1] = leftPoints[0].transform.position;
testVec[2] = leftPoints[1].transform.position;
textInt[0] = 0;
textInt[1] = 1;
textInt[2] = 2;
//Debug.Log("point local: " + centerLinePoints[0].transform.localPosition);
//Debug.Log("point global : " + centerLinePoints[0].transform.position);
//Debug.Log("vertice " + testVec[0]);
testmesh.Clear();
testmesh.vertices = testVec;
testmesh.triangles = textInt;
}
Vector3 LinearBezierCurves(Vector3 _pointStart, Vector3 _pointEnd, float t)
{// P0 P1
//P(t) = P0 + t * (P1 – P0) = (1 - t) P0 + t * P1 , 0 < t < 1
Vector3 p = Vector3.zero;
p = _pointStart + t * (_pointEnd - _pointStart);
return p;
}
Vector3 QuadraticBezierCurves(Vector3 _pointStart, Vector3 _pointEnd, Vector3 _pointControl, float t)
{ // P0 P1 P2
// P(t) = (1-t)^2 * P0 + 2(1-t) t * P2 + t^2 * P1 , 0 < t < 1
// uu u2 tt
Vector3 p = Vector3.zero;
float u = 1 - t;
float tt = t * t;
float uu = u * u;
float u2 = u * 2;
p = uu * _pointStart;
p += u2 * t * _pointControl;
p += tt * _pointEnd;
return p;
}
Vector3 CubicBezierCurve(Vector3 _pointStart, Vector3 _pointEnd, Vector3 _pointControlOne, Vector3 _pointControlTwo, float t)
{ // P0 P1 P2 P3
//P(t) = (1-t)^3 * P0 + 3 (1-t)^2 * t * P2 +3(1-t) * t^2 * P3 + t^3 * P1 , 0 < t< 1
// uuu uu u
Vector3 p = Vector3.zero;
float u = 1 - t;
float uu = u * u;
float uuu = u * u * u;
float tt = t * t;
float ttt = t * t * t;
return p;
}
private void MakeMeshData(Vector3 meshPointOne, Vector3 meshPointTwo, Vector3 meshPointThree, int index)
{
corridorVertices[index - 3] = meshPointOne;
corridorVertices[index - 2] = meshPointTwo;
corridorVertices[index - 1] = meshPointThree;
corridorTrangle[index - 3] = index - 3;
corridorTrangle[index - 2] = index - 2;
corridorTrangle[index - 1] = index - 1;
}
//private void CreateMesh()
//{
// roomMesh.Clear();
// roomMesh.vertices = roomVertices;
// roomMesh.triangles = roomTrangle;
//}
}
The mesh is always expressed in relation to its root transform. In order to use global positions use Transform.TransformPoint (or transform.InverseTransformPoint) to convert them to local space, i.e. all points must be expressed relative to the center of the gameobejct that will be displaying the mesh.
Related
public class path : MonoBehaviour
{
[Header("Line renderer veriables")]
public LineRenderer line;
[Range(2, 30)]
public int resolution;
Rigidbody rb;
[Header("Formula variables")]
public Vector3 velocity;
public float yLimit;
private float g;
[Header("Linecast variables")]
[Range(2, 30)]
public int linecastResolution;
public LayerMask canHit;
public Rigidbody ballRigid;
public open2close claw;
private void Start()
{
rb = GetComponent<Rigidbody>();
g = Mathf.Abs(Physics.gravity.y);
}
private void Update()
{
if(claw.isClosed)
RenderArc();
}
private void RenderArc()
{
line.positionCount = resolution + 1;
line.SetPositions(CalculateLineArray());
}
private Vector3[] CalculateLineArray()
{
Vector3[] lineArray = new Vector3[resolution + 1];
var lowestTimeValueX = MaxTimeX() / resolution;
var lowestTimeValueZ = MaxTimeZ() / resolution;
var lowestTimeValue = lowestTimeValueX > lowestTimeValueZ ? lowestTimeValueZ : lowestTimeValueX;
for (int i = 0; i < lineArray.Length; i++)
{
var t = lowestTimeValue * i;
lineArray[i] = CalculateLinePoint(t);
}
return lineArray;
}
private Vector3 HitPosition()
{
var lowestTimeValue = MaxTimeY() / linecastResolution;
for (int i = 0; i < linecastResolution + 1; i++)
{
RaycastHit rayHit;
var t = lowestTimeValue * i;
var tt = lowestTimeValue * (i + 1);
if (Physics.Linecast(CalculateLinePoint(t), CalculateLinePoint(tt), out rayHit, canHit))
return rayHit.point;
}
return CalculateLinePoint(MaxTimeY());
}
private Vector3 CalculateLinePoint(float t)
{
float x = rb.velocity.x * t;
float z = rb.velocity.z * t;
float y = (rb.velocity.y * t) - (g * Mathf.Pow(t, 2) / 2);
return new Vector3(x + transform.position.x, y + transform.position.y, z + transform.position.z);
}
private float MaxTimeY()
{
var v = rb.velocity.y;
var vv = v * v;
var t = (v + Mathf.Sqrt(vv + 2 * g * (transform.position.y - yLimit))) / g;
return t;
}
private float MaxTimeX()
{
if (IsValueAlmostZero(rb.velocity.x))
SetValueToAlmostZero(ref velocity.x);
var x = rb.velocity.x;
var t = (HitPosition().x - transform.position.x) / x;
return t;
}
private float MaxTimeZ()
{
if (IsValueAlmostZero(rb.velocity.z))
SetValueToAlmostZero(ref velocity.z);
var z = rb.velocity.z;
var t = (HitPosition().z - transform.position.z) / z;
return t;
}
private bool IsValueAlmostZero(float value)
{
return value < 0.0001f && value > -0.0001f;
}
private void SetValueToAlmostZero(ref float value)
{
value = 0.0001f;
}
public void SetVelocity(Vector3 velocity)
{
this.velocity = velocity;
}
}
I have this code but for some reason it shows these errors:
*Invalid AABB a
*Invalid AABB a
*UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
*Assertion failed on expression: 'IsFinite(outDistanceForSort)'
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
My trajectory isnt even showing anymore. ANyone know how to fix this?
I try splice mesh by intersect plane, but get wrong result.
my code (I slice mesh by plane with calc side from plane positive or negative and create accordingly place vertics in separte arrays (for negative and positive), if triangle belong to both side, then I calc intersections points and build new triangles:
public void SliceIt()
{
Mesh mesh = GetComponent<MeshFilter>().sharedMesh;
gameObject.name = "v1";
Vector3[] vertices = mesh.vertices;
Mesh cutplanemesh = cutplane.GetComponent<MeshFilter>().sharedMesh;
Vector3[] cutplanevertices = cutplanemesh.vertices;
p1 = cutplane.TransformPoint(cutplanevertices[40]);
p2 = cutplane.TransformPoint(cutplanevertices[20]);
p3 = cutplane.TransformPoint(cutplanevertices[0]);
var myplane = new Plane(p1, p2, p3);
Vector3[] vertics = mesh.vertices;
int[] triangles = mesh.triangles;
var side = new bool[vertics.Length];
for (var i = vertics.Length - 1; i >= 0; i--)
{
vertics[i] = transform.TransformPoint(vertics[i]);
side[i] = myplane.GetSide((vertics[i]));
}
var verticsPositive = new List<Vector3>();
var verticsNegative = new List<Vector3>();
var trianglesPositive = new List<int>();
var trianglesNegative = new List<int>();
for (var trix = triangles.Length - 3; trix >= 0; trix -= 3)
{
var index0 = triangles[trix];
var index1 = triangles[trix + 1];
var index2 = triangles[trix + 2];
var point0 = vertics[index0];
var point1 = vertics[index1];
var point2 = vertics[index2];
Debug.Log(point0 + " " + point1 + " " + point2);
if (side[index1] != side[index2] || side[index0] != side[index1] || side[index2] != side[index0])
{
if (side[index0] == side[index1])
Intersect(point0, point1, point2, myplane, side[index0], verticsPositive, verticsNegative, trianglesPositive, trianglesNegative);
else if (side[index0] == side[index2])
Intersect(point0, point2, point1, myplane, side[index0], verticsPositive, verticsNegative, trianglesPositive, trianglesNegative);
else if (side[index1] == side[index2])
Intersect(point1, point2, point0, myplane, side[index1], verticsPositive, verticsNegative, trianglesPositive, trianglesNegative);
}
else
{
if (side[index1])
{
trianglesPositive.Add(verticsPositive.Count + 2);
trianglesPositive.Add(verticsPositive.Count + 1);
trianglesPositive.Add(verticsPositive.Count + 0);
verticsPositive.Add(point2);
verticsPositive.Add(point1);
verticsPositive.Add(point0);
}
else
{
trianglesNegative.Add(verticsNegative.Count + 2);
trianglesNegative.Add(verticsNegative.Count + 1);
trianglesNegative.Add(verticsNegative.Count + 0);
verticsNegative.Add(point2);
verticsNegative.Add(point1);
verticsNegative.Add(point0);
}
}
}
var go1 = new GameObject();
go1.name = "positive";
var meshFilter = go1.AddComponent<MeshFilter>();
go1.AddComponent<MeshRenderer>();
var meshPositive = new Mesh();
meshPositive.vertices = verticsPositive.ToArray();
meshPositive.triangles = trianglesPositive.ToArray();
meshPositive.RecalculateBounds();
meshPositive.RecalculateNormals();
meshFilter.sharedMesh = meshPositive;
var go2 = new GameObject();
go2.name = "negative";
var meshFilter2 = go2.AddComponent<MeshFilter>();
go2.AddComponent<MeshRenderer>();
var meshNegative = new Mesh();
meshNegative.vertices = verticsNegative.ToArray();
meshNegative.triangles = trianglesNegative.ToArray();
meshNegative.RecalculateBounds();
meshNegative.RecalculateNormals();
meshFilter2.sharedMesh = meshNegative;
}
public void Intersect(Vector3 point0, Vector3 point1, Vector3 point2, Plane myplane, bool side, List<Vector3> verticsPositive, List<Vector3> verticsNegative, List<int> trianglesPositive,
List<int> trianglesNegative)
{
Vector3 pointIntersection1 = Vector3.zero;
var vector1 = point2 - point0;
var isIntersect1 = Math3d.LinePlaneIntersection(out pointIntersection1, point0, vector1, myplane.normal, p1);
Debug.Log("isIntersect " + isIntersect1 + " pointIntersection" + pointIntersection1);
Vector3 pointIntersection2 = Vector3.zero;
var vector2 = point2 - point1;
var isIntersect2 = Math3d.LinePlaneIntersection(out pointIntersection2, point1, vector2, myplane.normal, p1);
Debug.Log("isIntersect2 " + isIntersect1 + " pointIntersection2" + pointIntersection1);
if (side)
{
trianglesPositive.Add(verticsPositive.Count);
trianglesPositive.Add(verticsPositive.Count + 1);
trianglesPositive.Add(verticsPositive.Count + 2);
verticsPositive.Add(point0);
verticsPositive.Add(point1);
verticsPositive.Add(pointIntersection1);
trianglesPositive.Add(verticsPositive.Count);
trianglesPositive.Add(verticsPositive.Count + 1);
trianglesPositive.Add(verticsPositive.Count + 2);
verticsPositive.Add(point0);
verticsPositive.Add(pointIntersection1);
verticsPositive.Add(pointIntersection2);
}
else
{
trianglesNegative.Add(verticsNegative.Count);
trianglesNegative.Add(verticsNegative.Count + 1);
trianglesNegative.Add(verticsNegative.Count + 2);
verticsNegative.Add(point0);
verticsNegative.Add(point1);
verticsNegative.Add(pointIntersection1);
trianglesNegative.Add(verticsNegative.Count);
trianglesNegative.Add(verticsNegative.Count + 1);
trianglesNegative.Add(verticsNegative.Count + 2);
verticsNegative.Add(point0);
verticsNegative.Add(pointIntersection1);
verticsNegative.Add(pointIntersection2);
}
}
public static bool LinePlaneIntersection(out Vector3 intersection, Vector3 linePoint, Vector3 lineVec, Vector3 planeNormal, Vector3 planePoint)
{
float length;
float dotNumerator;
float dotDenominator;
Vector3 vector;
intersection = Vector3.zero;
dotNumerator = Vector3.Dot((planePoint - linePoint), planeNormal);
dotDenominator = Vector3.Dot(lineVec, planeNormal);
if (dotDenominator != 0.0f)
{
length = dotNumerator / dotDenominator;
vector = SetVectorLength(lineVec, length);
intersection = linePoint + vector;
return true;
}
else
return false;
}
I've some problem when draw manual in unity 2d.
I used list vector to draw polygon, but I can't fill it.
I also read this tutorial: http://forum.unity3d.com/threads/draw-polygon.54092/
But it's seem I need to convert polygon to triangles.(because my polygon is complex so convert to triangles is hard. I need to use some algorithm like Ear clipping...).
Please help me an easy way to fill it. (I think unity is top of game engine, then have some way to do it easiest).
Thanks so so much.
You are stuck with converting to mesh to get fill to work... GPUs(shaders) can only fill the interior spaces of triangles... This is fairly easy if you are working with closed convex polygons. Polygons with concave sections will take a bit more complicated algorithm to convert to mesh, but it seems you've already done some research on the subject (you mentioned ear clipping).
Good luck implementing your polygon list to triangle algo :)
I can offer Poisson-Disc algorithm remodel UniformPoissonDiskSampler.cs like :
using System;
using System.Collections.Generic;
using UnityEngine;
namespace AwesomeNamespace
{
public static class UniformPoissonDiskSampler
{
public const int DefaultPointsPerIteration = 30;
static readonly float SquareRootTwo = (float)Math.Sqrt(2);
struct Settings
{
public UnityEngine.Vector2 TopLeft, LowerRight, Center;
public UnityEngine.Vector2 Dimensions;
public float? RejectionSqDistance;
public float MinimumDistance;
public float CellSize;
public int GridWidth, GridHeight;
}
struct State
{
public UnityEngine.Vector2?[,] Grid;
public List<UnityEngine.Vector2> ActivePoints, Points;
}
public static List<UnityEngine.Vector2> SampleCircle(UnityEngine.Vector2 center, float radius, float minimumDistance)
{
return SampleCircle(center, radius, minimumDistance, DefaultPointsPerIteration);
}
public static List<UnityEngine.Vector2> SampleCircle(UnityEngine.Vector2 center, float radius, float minimumDistance, int pointsPerIteration)
{
return Sample(center - new UnityEngine.Vector2(radius, radius), center + new UnityEngine.Vector2(radius, radius), radius, minimumDistance, pointsPerIteration, null);
}
public static List<UnityEngine.Vector2> SampleRectangle(UnityEngine.Vector2 topLeft, UnityEngine.Vector2 lowerRight, float minimumDistance)
{
return SampleRectangle(topLeft, lowerRight, minimumDistance, DefaultPointsPerIteration);
}
public static List<UnityEngine.Vector2> SampleRectangle(UnityEngine.Vector2 topLeft, UnityEngine.Vector2 lowerRight, float minimumDistance, int pointsPerIteration)
{
return Sample(topLeft, lowerRight, null, minimumDistance, pointsPerIteration, null);
}
public static List<UnityEngine.Vector2> SamplePolygon(UnityEditor.Experimental.TerrainAPI.Processing.InMetric metric, float minimumDistance)
{
return Sample(null, null, null, minimumDistance, DefaultPointsPerIteration, metric);
}
static List<UnityEngine.Vector2> Sample(UnityEngine.Vector2? topLeft, UnityEngine.Vector2? lowerRight, float? rejectionDistance, float minimumDistance, int pointsPerIteration, UnityEditor.Experimental.TerrainAPI.Processing.InMetric metric = null)
{
if (!topLeft.HasValue && !lowerRight.HasValue && metric != null)
{
topLeft = new Vector2(metric.minpointx, metric.minpointz);
lowerRight = new Vector2(metric.maxpointx, metric.maxpointz);
}
var settings = new Settings
{
TopLeft = (Vector2)topLeft,
LowerRight = (Vector2)lowerRight,
Dimensions = (Vector2)lowerRight - (Vector2)topLeft,
Center = ((Vector2)topLeft + (Vector2)lowerRight) / 2,
CellSize = minimumDistance / SquareRootTwo,
MinimumDistance = minimumDistance,
RejectionSqDistance = rejectionDistance == null ? null : rejectionDistance * rejectionDistance
};
settings.GridWidth = (int)(settings.Dimensions.x / settings.CellSize) + 1;
settings.GridHeight = (int)(settings.Dimensions.y / settings.CellSize) + 1;
// Debug.Log("settings.GridWidth"+settings.GridWidth+"settings.GridHeight"+settings.GridHeight);
var state = new State
{
Grid = new UnityEngine.Vector2?[settings.GridWidth, settings.GridHeight],
ActivePoints = new List<UnityEngine.Vector2>(),
Points = new List<UnityEngine.Vector2>()
};
AddFirstPoint(ref settings, ref state, (metric == null) ? null : metric);
while (state.ActivePoints.Count != 0)
{
var listIndex = RandomHelper.Random.Next(state.ActivePoints.Count);
var point = state.ActivePoints[listIndex];
var found = false;
for (var k = 0; k < pointsPerIteration; k++)
found |= AddNextPoint(point, ref settings, ref state, (metric == null) ? null : metric);
if (!found)
state.ActivePoints.RemoveAt(listIndex);
}
return state.Points;
}
static void AddFirstPoint(ref Settings settings,
ref State state,
UnityEditor.Experimental.TerrainAPI.Processing.InMetric metric = null)
{
var added = false;
while (!added)
{
var d = RandomHelper.Random.NextDouble();
var xr = settings.TopLeft.x + settings.Dimensions.x * d;
d = RandomHelper.Random.NextDouble();
var yr = settings.TopLeft.y + settings.Dimensions.y * d;
var p = new UnityEngine.Vector2((float)xr, (float)yr);
if (settings.RejectionSqDistance != null && DistanceSquared(settings.Center, p) > settings.RejectionSqDistance)
continue;
added = true;
if (UnityEditor.Experimental.TerrainAPI.Processing.figures_Included(p.x, p.y, metric.metricIn, metric.count) == true)
{
var index = Denormalize(p, settings.TopLeft, settings.CellSize);
state.Grid[(int)index.x, (int)index.y] = p;
state.ActivePoints.Add(p);
state.Points.Add(p);
}
else
{
AddFirstPoint(ref settings, ref state, metric);
}
}
}
static float DistanceSquared(Vector2 A, Vector2 B)
{
return (float)Math.Pow(Math.Sqrt(Math.Pow((A.x - B.x), 2) + Math.Pow((A.y - B.y), 2)), 2);
}
static bool AddNextPoint(UnityEngine.Vector2 point,
ref Settings settings,
ref State state,
UnityEditor.Experimental.TerrainAPI.Processing.InMetric metric = null)
{
var found = false;
var q = GenerateRandomAround(point, settings.MinimumDistance);
if (metric != null)
{
if (UnityEditor.Experimental.TerrainAPI.Processing.figures_Included(q.x, q.y, metric.metricIn, metric.count) == true &&
q.x >= settings.TopLeft.x && q.x < settings.LowerRight.x &&
q.y > settings.TopLeft.y && q.y < settings.LowerRight.y &&
(settings.RejectionSqDistance == null || DistanceSquared(settings.Center, q) <= settings.RejectionSqDistance))
{
var qIndex = Denormalize(q, settings.TopLeft, settings.CellSize);
var tooClose = false;
for (var i = (int)Math.Max(0, qIndex.x - 2); i < Math.Min(settings.GridWidth, qIndex.x + 3) && !tooClose; i++)
for (var j = (int)Math.Max(0, qIndex.y - 2); j < Math.Min(settings.GridHeight, qIndex.y + 3) && !tooClose; j++)
if (state.Grid[i, j].HasValue && Vector2.Distance(state.Grid[i, j].Value, q) < settings.MinimumDistance)
tooClose = true;
if (!tooClose)
{
found = true;
state.ActivePoints.Add(q);
state.Points.Add(q);
state.Grid[(int)qIndex.x, (int)qIndex.y] = q;
}
}
}
else
{
if (q.x >= settings.TopLeft.x && q.x < settings.LowerRight.x &&
q.y > settings.TopLeft.y && q.y < settings.LowerRight.y &&
(settings.RejectionSqDistance == null || DistanceSquared(settings.Center, q) <= settings.RejectionSqDistance))
{
var qIndex = Denormalize(q, settings.TopLeft, settings.CellSize);
var tooClose = false;
for (var i = (int)Math.Max(0, qIndex.x - 2); i < Math.Min(settings.GridWidth, qIndex.x + 3) && !tooClose; i++)
for (var j = (int)Math.Max(0, qIndex.y - 2); j < Math.Min(settings.GridHeight, qIndex.y + 3) && !tooClose; j++)
if (state.Grid[i, j].HasValue && Vector2.Distance(state.Grid[i, j].Value, q) < settings.MinimumDistance)
tooClose = true;
if (!tooClose)
{
found = true;
state.ActivePoints.Add(q);
state.Points.Add(q);
state.Grid[(int)qIndex.x, (int)qIndex.y] = q;
}
}
}
return found;
}
static Vector2 GenerateRandomAround(Vector2 center, float minimumDistance)
{
var d = RandomHelper.Random.NextDouble();
var radius = minimumDistance + minimumDistance * d;
d = RandomHelper.Random.NextDouble();
var angle = MathHelper.TwoPi * d;
var newX = radius * Math.Sin(angle);
var newY = radius * Math.Cos(angle);
return new Vector2((float)(center.x + newX), (float)(center.y + newY));
}
static Vector2 Denormalize(Vector2 point, Vector2 origin, double cellSize)
{
return new Vector2((int)((point.x - origin.x) / cellSize), (int)((point.y - origin.y) / cellSize));
}
}
public static class RandomHelper
{
public static readonly System.Random Random = new System.Random();
}
public static class MathHelper
{
public const float Pi = (float)Math.PI;
public const float HalfPi = (float)(Math.PI / 2);
public const float TwoPi = (float)(Math.PI * 2);
}
}
figures_Included:
public static bool figures_Included(float xPoint, float yPoint, float[] metricIn, int n)
{
float X = xPoint;
float Y = yPoint;
int npol = n;
int i, j;
bool res = false;
float[] XYpol = metricIn;
for (i = 0, j = npol - 1; i < npol; j = i++)
{
if ((((XYpol[i * 2 + 1] <= Y) && (Y < XYpol[j * 2 + 1])) ||
((XYpol[j * 2 + 1] <= Y) && (Y < XYpol[i * 2 + 1]))) &&
(X < (XYpol[j * 2] - XYpol[i * 2]) * (Y - XYpol[i * 2 + 1]) /
(XYpol[j * 2 + 1] - XYpol[i * 2 + 1]) + XYpol[i * 2]))
{
res = !res;
}
}
return res;
}
and InMetric :
static public InMetric getmetricIn(List<Vector3> drawcoord, bool editingmode = true)
{
float mapoffsetx = 0;
float mapoffsety = 0;
if (editingmode == true)
{
mapoffsetx = Main.mainSatting.mapoffsetx;
mapoffsety = Main.mainSatting.mapoffsetz;
}
else
{
mapoffsetx = 0;
mapoffsety = 0;
}
if (drawcoord[0].x != drawcoord[drawcoord.Count - 1].x && drawcoord[0].z != drawcoord[drawcoord.Count - 1].z) //если линия, ограничивающая полигон не замкнута
drawcoord.Add(drawcoord[0]); //добавляем замыкающую вершину
float[] metricIn = new float[drawcoord.Count * 2]; //дополнительный массив вершин, пересчитанный для проверки нахождения точки внутри полигона
drawcoord[0] = new Vector3(drawcoord[0].x - mapoffsetx, 0, drawcoord[0].z - mapoffsety); //расчет 0-ой вершины в единицах Unity (метры)
metricIn[0] = drawcoord[0].x;
metricIn[1] = drawcoord[0].z; //запись 0-ой вершины в дополнительный массив. x-координаты под четными индексами, Z-координаты под нечетными индексами
float minpointx = drawcoord[0].x; //минимальная x-координата
float maxpointx = drawcoord[0].x; //максимальная х-координата
float minpointz = drawcoord[0].z; //минимальная y-координата
float maxpointz = drawcoord[0].z; //максимальная у-координата
/*Цикл обработки вершин. начинается 1-ой вершины*/
for (int i = 1; i < drawcoord.Count; i++)
{
drawcoord[i] = new Vector3(drawcoord[i].x - mapoffsetx, 0, drawcoord[i].z - mapoffsety); //расчет i-ой вершины в единицах Unity (метры)
metricIn[i * 2] = drawcoord[i].x; //запись i-ой вершины в дополнительный массив. x-координаты под четными индексами
metricIn[i * 2 + 1] = drawcoord[i].z; //запись i-ой вершины в дополнительный массив. z-координаты под нечетными индексами
/*поиск максимальных и минимальных координат по x и максимальных и минимальных координат по z*/
if (drawcoord[i].x < minpointx)
minpointx = drawcoord[i].x;
if (drawcoord[i].x > maxpointx)
maxpointx = drawcoord[i].x;
if (drawcoord[i].z < minpointz)
minpointz = drawcoord[i].z;
if (drawcoord[i].z > maxpointz)
maxpointz = drawcoord[i].z;
}
InMetric metric = new InMetric();
metric.metricIn = metricIn;
metric.minpointx = minpointx;
metric.maxpointx = maxpointx;
metric.minpointz = minpointz;
metric.maxpointz = maxpointz;
metric.drawcoord = drawcoord;
metric.count = drawcoord.Count;
return metric;
}
public class InMetric
{
public float minpointx { get; set; }
public float maxpointx { get; set; }
public float minpointz { get; set; }
public float maxpointz { get; set; }
public float[] metricIn { get; set; }
public List<Vector3> drawcoord { get; set; }
public int count { get; set; }
}
I really hope you guys can help me with my problem, this was my last resort and im super frustrated.
I'm creating a 2D Side-Scroller game and while coding the player file, I've ran into a very annoying thing that I don't know where the problem is. Everything else in the player is fine, what happens is that if the player is walking on a slant, and then comes off; the gravity (I'm assuming) is being messed with and when your in the air he just floats down instead of falling; also if you jump (after walking on the slant) he just does a teeeeeeny tiny hop. I have debugged the whole file several times and can't seem to figure it out.
If someone would please help, I'll put the whole player file. If you have a 2D sidescroller game in unity, you can just put this file on a gameobject with a rigidBody2D and isKinemic is true..
using UnityEngine;
using System.Collections;
using System;
public class PlayerControl : MonoBehaviour {
private Animator anim;
public static PlayerControl instance;
public static bool isShooting;
[HideInInspector]
public bool facingRight;
private float normalSpeed;
private static readonly float slopeLimitTangent = Mathf.Tan(75f * Mathf.Deg2Rad);
public float maxSpeed = 8f;
private float speedAccelerationOnGround = 10f;
private float speedAccelerationInAir = 5f;
private Vector2 velocity {get {return vel;}}
public int health = 100;
private bool isDead;
private const float skinWidth = .02f;
private const int horizRays = 8;
private const int vertRays = 4;
public enum JumpBehavior {
JumpOnGround,
JumpAnywhere,
CantJump
};
public JumpBehavior jumpWhere;
private float jumpIn;
public float jumpFreq = 0.25f;
public float jumpMag = 16;
public LayerMask whatIsGround;
private bool grounded { get { return colBelow; } }
private bool cooldown;
public GameObject standingOn {get; private set;}
public Vector3 platformVelocity {get;private set;}
public bool canJump { get {
if (jumpWhere == JumpBehavior.JumpAnywhere)
return jumpIn <= 0;
if (jumpWhere == JumpBehavior.JumpOnGround)
return grounded;
return false;
}
}
public bool colRight { get; set;}
public bool colLeft { get; set;}
public bool colAbove{ get; set;}
public bool colBelow{ get; set;}
public bool upSlope{ get; set;}
public bool downSlope{get;set;}
public float slopeAngle {get;set;}
public bool hasCollisions { get { return colRight || colLeft || colAbove || colBelow; }
}
private float
vertDistanceBetweenRays,
horizDistanceBetweenRays;
private Vector3 raycastTopLeft;
private Vector3 raycastBottomRight;
private Vector3 raycastBottomLeft;
private Vector2 maxVelocity = new Vector2(float.MaxValue,
float.MaxValue);
private Vector2 vel;
[Range(0, 90)]
public float slopeLimit = 30;
public float gravity = -15;
private GameObject lastStandingOn;
private Vector3 activeGlobalPlatformPoint;
private Vector3 activeLocalPlatformPoint;
public static int scene = 0;
void Start () {
instance = this;
anim = GetComponent<Animator> ();
float colliderWidth = GetComponent<BoxCollider2D>().size.x * Mathf.Abs
(transform.localScale.x) - (2 * skinWidth);
horizDistanceBetweenRays = colliderWidth / (vertRays - 1);
float colliderHeight = GetComponent<BoxCollider2D>().size.y * Mathf.Abs
(transform.localScale.y) - (2 * skinWidth);
vertDistanceBetweenRays = colliderHeight / (horizRays - 1);
}
void Update () {
if (!isDead)
HandleInput();
float movementFactor = grounded ? speedAccelerationOnGround : speedAccelerationInAir;
if (isDead)
HorizForce(0);
else
HorizForce(Mathf.Lerp(velocity.x, normalSpeed * maxSpeed, Time.deltaTime * movementFactor));
anim.SetBool("Grounded", grounded);
anim.SetBool("Dead", isDead);
anim.SetFloat("Speed", Mathf.Abs(velocity.x) / maxSpeed);
}
public void LateUpdate() {
jumpIn -= Time.deltaTime;
vel.y += gravity * Time.deltaTime;
Move (vel * Time.deltaTime);
}
public void AddForce(Vector2 force) {
vel += force;
}
public void SetForce(Vector2 force) {
vel = force;
}
public void HorizForce(float x) {
vel.x = x;
}
public void VertForce(float y) {
vel.y = y;
}
public void Jump() {
AddForce(new Vector2(0, jumpMag));
jumpIn = jumpFreq;
anim.SetTrigger("Jump");
}
void HandleInput() {
float h = Input.GetAxis("Horizontal");
normalSpeed = h;
if (h < 0) {
if (!facingRight)
Flip ();
facingRight = true;
} else
if (h > 0) {
if (facingRight)
Flip ();
facingRight = false;
} else
normalSpeed = 0;
if (canJump && Input.GetButtonDown("Jump"))
Jump();
if (Input.GetButton("melee") && !Input.GetButtonDown ("Fire1") && MeleeAttack.canHit) {
anim.SetTrigger ("Attack");
MeleeAttack.canHit = false;
MeleeAttack.instance.cooldown ();
}
}
private void Flip() {
transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);
facingRight = transform.localScale.x > 0;
}
void ResetColliders() {
colLeft = false;
colRight = false;
colAbove = false;
colBelow = false;
colLeft = false;
slopeAngle = 0;
}
void Move(Vector2 deltaMove) {
bool wasGrounded = colBelow;
ResetColliders();
HandlePlatforms ();
CalcRayOrigins();
if (deltaMove.y < 0 && wasGrounded)
HandleVerticalSlope(ref deltaMove);
if (Mathf.Abs(deltaMove.x) > 0.001f)
MoveHoriz(ref deltaMove);
MoveVert(ref deltaMove);
//CorrectHorizPlacement(ref deltaMove, true);
//CorrectHorizPlacement(ref deltaMove, false);
transform.Translate(deltaMove, Space.World);
if (Time.deltaTime > 0)
vel = deltaMove / Time.deltaTime;
vel.x = Mathf.Min(vel.x, maxVelocity.x);
vel.y = Mathf.Min(vel.y, maxVelocity.y);
if (upSlope)
vel.y = 0;
if (standingOn != null) {
activeGlobalPlatformPoint = transform.position;
activeLocalPlatformPoint = standingOn.transform.InverseTransformPoint(transform.position);
if (lastStandingOn != standingOn) {
if (lastStandingOn != null)
lastStandingOn.SendMessage("ControllerExit2D", this, SendMessageOptions.DontRequireReceiver);
standingOn.SendMessage("ControllerEnter2D", this, SendMessageOptions.DontRequireReceiver);
lastStandingOn = standingOn;
} else if (standingOn != null)
standingOn.SendMessage("ControllerStay2D", this, SendMessageOptions.DontRequireReceiver);
else if (lastStandingOn != null) {
lastStandingOn.SendMessage("ControllerExit2D", this, SendMessageOptions.DontRequireReceiver);
lastStandingOn = null;
}
}
}
void MoveHoriz(ref Vector2 deltaMove) {
bool goingRight = deltaMove.x > 0;
float rayDistance = Mathf.Abs (deltaMove.x) + skinWidth;
Vector2 rayDirection = goingRight ? Vector2.right : -Vector2.right;
Vector3 rayOrigin = goingRight ? raycastBottomRight : raycastBottomLeft;
for (int i = 0; i < horizRays; i++) {
Vector2 rayVect = new Vector2(rayOrigin.x, rayOrigin.y + (i * vertDistanceBetweenRays));
Debug.DrawRay(rayVect, rayDirection * rayDistance, Color.red);
RaycastHit2D raycastHit = Physics2D.Raycast(rayVect, rayDirection, rayDistance, whatIsGround);
if (!raycastHit) continue;
if (i == 0 && HandleHorizontalSlope(ref deltaMove, Vector2.Angle(raycastHit.normal, Vector2.up), goingRight))
break;
deltaMove.x = raycastHit.point.x - rayVect.x;
rayDistance = Mathf.Abs (deltaMove.x);
if (goingRight) {
deltaMove.x -= skinWidth;
colRight = true;
} else {
deltaMove.x += skinWidth;
colLeft = true;
}
if (rayDistance < skinWidth + .0001f)
break;
}
}
private void HandlePlatforms() {
if (standingOn != null) {
Vector3 newGlobalPlatformPoint = standingOn.transform.TransformPoint(activeLocalPlatformPoint);
Vector3 moveDistance = newGlobalPlatformPoint - activeGlobalPlatformPoint;
if (moveDistance != Vector3.zero)
transform.Translate(moveDistance, Space.World);
platformVelocity = (newGlobalPlatformPoint - activeGlobalPlatformPoint) / Time.deltaTime;
} else
platformVelocity = Vector3.zero;
standingOn = null;
}
private void MoveVert(ref Vector2 deltaMovement) {
bool isGoingUp = deltaMovement.y > 0;
float rayDistance = Mathf.Abs(deltaMovement.y) + skinWidth;
Vector2 rayDirection = isGoingUp ? Vector2.up : -Vector2.up;
Vector2 rayOrigin = isGoingUp ? raycastTopLeft : raycastBottomLeft;
rayOrigin.x += deltaMovement.x;
float standingOnDistance = float.MaxValue;
for (int i = 0; i < vertRays; i++) {
Vector2 rayVector = new Vector2(rayOrigin.x + (i * horizDistanceBetweenRays), rayOrigin.y);
Debug.DrawRay(rayVector, rayDirection * rayDistance, Color.red);
RaycastHit2D rayCastHit = Physics2D.Raycast(rayVector, rayDirection, rayDistance, whatIsGround);
if (!rayCastHit)
continue;
if (!isGoingUp) {
float verticalDistanceToHit = transform.position.y - rayCastHit.point.y;
if (verticalDistanceToHit < standingOnDistance) {
standingOnDistance = verticalDistanceToHit;
standingOn = rayCastHit.collider.gameObject;
}
}
deltaMovement.y = rayCastHit.point.y - rayVector.y;
rayDistance = Mathf.Abs(deltaMovement.y);
if (isGoingUp) {
deltaMovement.y -= skinWidth;
colAbove = true;
} else {
deltaMovement.y += skinWidth;
colBelow = true;
}
if (!isGoingUp && deltaMovement.y > .0001f)
upSlope = true;
if (rayDistance < skinWidth + .0001f)
break;
}
}
private void HandleVerticalSlope(ref Vector2 deltaMove) {
float center = (raycastBottomLeft.x + raycastBottomRight.x) / 2;
Vector2 direction = -Vector2.up;
float slopeDistance = slopeLimitTangent + (raycastBottomRight.x - center);
Vector2 slopeRayVector = new Vector2(center, raycastBottomLeft.y);
Debug.DrawRay(slopeRayVector, direction * slopeDistance, Color.yellow);
RaycastHit2D rayCastHit = Physics2D.Raycast(slopeRayVector, direction, slopeDistance, whatIsGround);
if (!rayCastHit)
return;
float angle = Vector2.Angle(rayCastHit.normal, Vector2.up);
if (Mathf.Abs (angle) < .0001f)
return;
downSlope = true;
slopeAngle = angle;
deltaMove.y = rayCastHit.point.y - slopeRayVector.y;
transform.rotation = Quaternion.Euler (0, 0, facingRight ? angle : -angle);
}
private bool HandleHorizontalSlope(ref Vector2 deltaMove, float angle, bool isGoingRight) {
if (Mathf.RoundToInt(angle) == 90)
return false;
if (angle > slopeLimit) {
deltaMove.x = 0;
return true;
}
if (deltaMove.y > .07f)
return true;
deltaMove.x += isGoingRight ? -skinWidth : skinWidth;
deltaMove.y = Mathf.Abs(Mathf.Tan(angle * Mathf.Deg2Rad) * deltaMove.x);
upSlope = true;
colBelow = true;
return true;
}
void CalcRayOrigins() {
Vector2 size = new Vector2(GetComponent<BoxCollider2D>().size.x * Mathf.Abs(transform.localScale.x), GetComponent<BoxCollider2D>().size.y * Mathf.Abs(transform.localScale.y)) / 2;
Vector2 center = new Vector2(GetComponent<BoxCollider2D>().center.x * transform.localScale.x, GetComponent<BoxCollider2D>().center.y * transform.localScale.y);
raycastTopLeft = transform.position + new Vector3(center.x - size.x + skinWidth, center.y + size.y - skinWidth);
raycastBottomRight = transform.position + new Vector3(center.x + size.x - skinWidth, center.y - size.y + skinWidth);
raycastBottomLeft = transform.position + new Vector3(center.x - size.x + skinWidth, center.y - size.y + skinWidth);
}
void CorrectHorizPlacement(ref Vector2 deltaMove, bool isRight) {
float halfWidth = (GetComponent<BoxCollider2D> ().size.x * transform.localScale.x) / 2f;
Vector3 rayOrigin = isRight ? raycastBottomRight : raycastBottomLeft;
if (isRight)
rayOrigin.x -= (halfWidth + skinWidth);
else
rayOrigin.x += (halfWidth + skinWidth);
Vector2 rayDirection = isRight ? Vector2.right : -Vector2.right;
float offset = 0;
for (int i = 1; i < horizRays - 1; i++) {
Vector2 rayVector = new Vector2(deltaMove.x + rayOrigin.x, deltaMove.y + rayOrigin.y + (i * vertDistanceBetweenRays));
RaycastHit2D raycastHit = Physics2D.Raycast(rayVector, rayDirection, halfWidth, whatIsGround);
if (!raycastHit) continue;
offset = isRight ? ((raycastHit.point.x - transform.position.x) - halfWidth) : (halfWidth - (transform.position.x - raycastHit.point.x));
deltaMove.x += offset;
}
}
}
please someone help.
I have a page curl code in Action Script and i want to use that code in my app which is developed using Xcode(Objective c). Can any one tell whether it is possible or not. If possible then please tell me how to do.
The action script code follows
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.GradientType;
import flash.display.PixelSnapping;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import asData.clsGlobalConstants;
import com.DaveLibrary.clsSupport;
import com.cupcake.Utils;
public class clsPageTurn extends Sprite
{
private var cMain:clsMain;
private var gc:clsGlobalConstants;
private var flipDirection:int;
private var pageWidth:Number;
private var pageHeight:Number;
private var pageWidthHeight:Number;
private var pivotY:Number;
private var NextPageLeft:BitmapData;
private var NextPageRight:BitmapData;
private var StationaryPage:Sprite;
private var StationaryPageMask:Sprite;
private var StationaryPageBitmap:Bitmap;
private var StationaryShadow:Sprite;
private var StationaryShadowMask:Sprite;
private var FlippingPage:Sprite;
private var FlippingPageBitmap:Bitmap;
private var FlippingPageMask:Sprite;
private var FlippingPageBorder:Sprite;
private var FlippingPageShadow:Sprite;
private var OutsideShadow:Sprite;
private var OutsideShadowMask:Sprite;
private var LeftRect:Rectangle;
private var RightRect:Rectangle;
private var LeftPoint:Point;
private var RightPoint:Point;
private var StaticLeftRect:Rectangle;
private var StaticRightRect:Rectangle;
private var StaticLeftPoint:Point;
private var StaticRightPoint:Point;
public var percentage:Number;
public var useShadows:Boolean = false;
public function clsPageTurn(Main:clsMain, FlipDirection:int, pWidth:Number = 1366, pHeight:Number = 768, xOffset:Number = -171)
{
// constructor code
cMain = Main;
gc = cMain.gc;
this.x = xOffset;
percentage = 0; // tracks the last percentage that was drawn.
StationaryPage = new Sprite();
StationaryPage.x = xOffset;
this.addChild(StationaryPage);
StationaryPageBitmap = new Bitmap();
StationaryPageBitmap.pixelSnapping = PixelSnapping.ALWAYS;
StationaryPage.addChild(StationaryPageBitmap);
StationaryPageMask = new Sprite();
StationaryPageMask.x = xOffset;
this.addChild(StationaryPageMask);
useShadows = !clsMain.isSlow;
if ( useShadows )
{
StationaryShadow = new Sprite();
StationaryShadow.x = xOffset;
this.addChild(StationaryShadow);
OutsideShadow = new Sprite();
OutsideShadow.x = xOffset;
this.addChild(OutsideShadow);
OutsideShadowMask = new Sprite();
OutsideShadowMask.x = xOffset;
this.addChild(OutsideShadowMask);
}
FlippingPage = new Sprite();
FlippingPage.x = xOffset;
this.addChild(FlippingPage);
FlippingPageBitmap = new Bitmap();
FlippingPageBitmap.pixelSnapping = PixelSnapping.ALWAYS;
FlippingPage.addChild(FlippingPageBitmap);
if ( useShadows )
{
FlippingPageBorder = new Sprite();
FlippingPage.addChild(FlippingPageBorder);
}
FlippingPageMask = new Sprite();
FlippingPageMask.x = xOffset;
this.addChild(FlippingPageMask);
if ( useShadows )
{
FlippingPageShadow = new Sprite();
FlippingPage.addChild(FlippingPageShadow);
}
// set the page width and height and other variables for this page flip object.
pageWidth = pWidth / 2; // the width is the width of one of our half pages, not the full screen width.
pageHeight = pHeight;
pageWidthHeight = pageWidth + pageHeight;
pivotY = (pageHeight/2) + pageWidth;
// rect and points for copying the halves.
LeftRect = new Rectangle(xOffset, 0, pageWidth, pageHeight);
RightRect = new Rectangle(pageWidth + xOffset, 0, pageWidth, pageHeight);
LeftPoint = new Point(xOffset,0);
RightPoint = new Point(pageWidth + xOffset, 0);
StaticLeftRect = new Rectangle(0, 0, pageWidth, pageHeight);
StaticRightRect = new Rectangle(pageWidth, 0, pageWidth, pageHeight);
StaticLeftPoint = new Point(0,0);
StaticRightPoint = new Point(pageWidth, 0);
flipDirection = FlipDirection;
// create our page halves.
NextPageLeft = new BitmapData(pageWidth, pageHeight, true, 0);
NextPageRight = new BitmapData(pageWidth, pageHeight, true, 0);
if(flipDirection > 0) {
StationaryPageBitmap.bitmapData = NextPageRight;
FlippingPageBitmap.bitmapData = NextPageLeft;
} else {
StationaryPageBitmap.bitmapData = NextPageLeft;
FlippingPageBitmap.bitmapData = NextPageRight;
}
// disable the mouse for this sprite so it doesn't trap events.
this.mouseEnabled = false;
this.mouseChildren = false;
}
public function destroy():void
{
this.graphics.clear();
if(this.parent != null) {
if(this.parent.contains(this)) {
this.parent.removeChild(this);
}
}
if(NextPageLeft != null) NextPageLeft.dispose();
NextPageLeft = null;
if(NextPageRight != null) NextPageRight.dispose();
NextPageRight = null;
if(StationaryPage != null) {
while(StationaryPage.numChildren < 0) {
StationaryPage.removeChildAt(0);
}
}
StationaryPage = null;
if(StationaryPageMask != null) StationaryPageMask.graphics.clear();
StationaryPageMask = null;
if(StationaryShadow != null) StationaryShadow.graphics.clear();
StationaryShadow = null;
if(StationaryShadowMask != null) StationaryShadowMask.graphics.clear();
StationaryShadowMask = null;
if(OutsideShadow != null) {
while(OutsideShadow.numChildren < 0) {
OutsideShadow.removeChildAt(0);
}
}
OutsideShadow = null;
if(OutsideShadowMask != null) OutsideShadowMask.graphics.clear();
OutsideShadowMask = null;
if(FlippingPage != null) {
while(FlippingPage.numChildren > 0) {
FlippingPage.removeChildAt(0);
}
}
FlippingPage = null;
if(FlippingPageMask != null) FlippingPageMask.graphics.clear();
FlippingPageMask = null;
if(FlippingPageShadow != null) FlippingPageShadow.graphics.clear();
FlippingPageShadow = null;
if(FlippingPageBitmap != null) {
if(FlippingPageBitmap.bitmapData != null) FlippingPageBitmap.bitmapData.dispose();
}
FlippingPageBitmap = null;
gc = null;
cMain = null;
}
public function Initialize( NextPage:BitmapData ):void
{
NextPageLeft.copyPixels(NextPage, StaticLeftRect, StaticLeftPoint);
NextPageRight.copyPixels(NextPage, StaticRightRect, StaticLeftPoint);
StationaryPageBitmap.smoothing = useShadows;
FlippingPageBitmap.smoothing = useShadows;
redraw(0);
}
public function InitializeDO( NextPage:DisplayObject ):void
{
var rect:Rectangle = NextPage.scrollRect;
NextPage.scrollRect = LeftRect;
NextPageLeft.draw( NextPage );
NextPage.scrollRect = RightRect;
NextPageRight.draw( NextPage );
NextPage.scrollRect = rect;
StationaryPageBitmap.smoothing = useShadows;
FlippingPageBitmap.smoothing = useShadows;
redraw(0);
}
public function InitializeHelperObjects():void
{
var bmData:BitmapData;
var m:Matrix;
var colors:Array;
var alphas:Array;
var ratios:Array;
var maxLength:Number = Math.sqrt((pageWidth * pageWidth)+(pageWidthHeight * pageWidthHeight));
var matrix:Matrix = new Matrix();
StationaryPageBitmap.x = ((flipDirection * pageWidth) / 2) - (pageWidth / 2);
StationaryPageBitmap.y = -pivotY - (pageHeight/2);
StationaryPage.x = pageWidth;
StationaryPage.y = pivotY + (pageHeight / 2);
StationaryPageMask.graphics.clear();
StationaryPageMask.graphics.beginFill(0x00FF00,1);
StationaryPageMask.graphics.drawRect(((flipDirection > 0) ? 0 : -pageWidth) , (-pivotY) - (pageWidthHeight / 2), pageWidth, pageWidthHeight);
StationaryPageMask.graphics.endFill();
StationaryPageMask.transform.matrix = new Matrix(1,0,0,1,pageWidth, pivotY + (pageHeight / 2));
colors = [gc.pageTurn_InsideShadow_Color, gc.pageTurn_InsideShadow_Color,gc.pageTurn_InsideShadow_Color,gc.pageTurn_InsideShadow_Color,gc.pageTurn_InsideShadow_Color];
alphas = [0,0,gc.pageTurn_InsideShadow_Stationary_Max,0,0];
ratios = [0,85,125,170,255];
matrix = new Matrix();
if ( useShadows )
{
StationaryShadow.graphics.clear();
StationaryShadow.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
StationaryShadow.graphics.drawRect(((flipDirection > 0) ? 0 : -pageWidth), (-pivotY) - (pageWidthHeight / 2), pageWidth, pageWidthHeight);
StationaryShadow.graphics.endFill();
StationaryShadow.transform.matrix = new Matrix(1,0,0,1,pageWidth, pivotY + (pageHeight / 2));
}
FlippingPageBitmap.x = ((-flipDirection * pageWidth) / 2) - (pageWidth / 2);
FlippingPageBitmap.y = (-pivotY) - (pageHeight / 2);
FlippingPage.transform.matrix = new Matrix(1,0,0,1,pageWidth, pivotY + (pageHeight / 2));
maxLength = Math.sqrt((pageWidth * pageWidth)+(pageWidthHeight * pageWidthHeight));
colors = [gc.pageTurn_InsideShadow_Color,gc.pageTurn_InsideShadow_Color,gc.pageTurn_InsideShadow_Color,gc.pageTurn_InsideShadow_Color];
alphas = [0, gc.pageTurn_InsideShadow_Flipping_Max, gc.pageTurn_InsideShadow_Flipping_Max, 0];
ratios = [0, 100, 150, 255];
matrix = new Matrix();
matrix.createGradientBox( pageWidth, FlippingPageBitmap.height, 0, 0, 0);
if ( useShadows )
{
FlippingPageShadow.graphics.clear();
FlippingPageShadow.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
FlippingPageShadow.graphics.drawRect(0, 0, FlippingPageBitmap.width, FlippingPageBitmap.height);
FlippingPageShadow.graphics.endFill();
FlippingPageShadow.transform.matrix = new Matrix(1,0,0,1,FlippingPageBitmap.x, FlippingPageBitmap.y);
}
FlippingPageMask.graphics.clear();
FlippingPageMask.graphics.beginFill(0xFF0000,1);
FlippingPageMask.graphics.drawRect(((-flipDirection * pageWidthHeight) / 2) - (pageWidthHeight/2), (-pivotY) - (pageWidthHeight / 2), pageWidthHeight, pageWidthHeight*2);
FlippingPageMask.graphics.endFill();
FlippingPageMask.transform.matrix = new Matrix(1,0,0,1,pageWidth, pivotY + (pageHeight / 2));
if ( useShadows )
{
OutsideShadow.graphics.clear();
OutsideShadow.graphics.beginFill(0x000000,cMain.gc.pageTurn_OutsideShadow_Alpha);
OutsideShadow.graphics.drawRect(FlippingPageBitmap.x, FlippingPageBitmap.y, FlippingPageBitmap.width, FlippingPageBitmap.height);
OutsideShadow.graphics.endFill();
OutsideShadow.transform.matrix = new Matrix(1,0,0,1,pageWidth, pivotY + (pageHeight / 2));
OutsideShadowMask.graphics.clear();
OutsideShadowMask.graphics.beginFill(0x0000FF,1);
OutsideShadowMask.graphics.drawRect(((-flipDirection * pageWidthHeight) / 2) - (pageWidthHeight/2), (-pivotY) - (pageWidthHeight / 2), pageWidthHeight, pageWidthHeight*2);
OutsideShadowMask.graphics.endFill();
OutsideShadowMask.transform.matrix = new Matrix(1,0,0,1,pageWidth, pivotY + (pageHeight / 2));
FlippingPageBorder.x = FlippingPageBitmap.x;
FlippingPageBorder.y = FlippingPageBitmap.y;
FlippingPageBorder.width = pageWidth;
FlippingPageBorder.height = pageHeight;
FlippingPageBorder.graphics.clear();
FlippingPageBorder.graphics.beginFill(0x000001, 1);
FlippingPageBorder.graphics.drawRect(0,0,gc.pageTurn_Border_Size, pageHeight);
FlippingPageBorder.graphics.endFill();
FlippingPageBorder.graphics.beginFill(0x000001, 1);
FlippingPageBorder.graphics.drawRect(gc.pageTurn_Border_Size,0,pageWidth-(gc.pageTurn_Border_Size*2), gc.pageTurn_Border_Size);
FlippingPageBorder.graphics.endFill();
FlippingPageBorder.graphics.beginFill(0x000001, 1);
FlippingPageBorder.graphics.drawRect(gc.pageTurn_Border_Size,pageHeight - gc.pageTurn_Border_Size,pageWidth - (gc.pageTurn_Border_Size*2), gc.pageTurn_Border_Size);
FlippingPageBorder.graphics.endFill();
FlippingPageBorder.graphics.beginFill(0x000001, 1);
FlippingPageBorder.graphics.drawRect(pageWidth - gc.pageTurn_Border_Size,0,gc.pageTurn_Border_Size, pageHeight);
FlippingPageBorder.graphics.endFill();
FlippingPageBorder.visible = true;
}
StationaryPage.mask = StationaryPageMask;
FlippingPage.mask = FlippingPageMask;
if ( useShadows ) OutsideShadow.mask = OutsideShadowMask;
}
public function redraw(Percentage:Number):void
{
percentage = Utils.Clamp( Percentage, 0, 1 );
var rot:Number = flipDirection * 45 * Percentage;
rotateSprite(FlippingPage, (flipDirection * 90) - rot * 2);
if ( useShadows )
{
FlippingPageShadow.alpha = 0;
StationaryShadow.alpha = clsSupport.GetBezier2DPercentage(0,0,1,1,Percentage);
FlippingPageBorder.alpha = gc.pageTurn_Border_Alpha * (1 - percentage);
rotateSprite(OutsideShadow, ((flipDirection * 90) - rot * 2) + (clsSupport.GetBezier2DPercentage(gc.pageTurn_OutsideShadow_OffsetStart, gc.pageTurn_OutsideShadow_OffsetEnd, gc.pageTurn_OutsideShadow_LeadIn, gc.pageTurn_OutsideShadow_LeadOut, Percentage) * -flipDirection));
rotateSprite(StationaryShadow, (flipDirection * 45) - rot );
rotateSprite(OutsideShadowMask, (flipDirection * 45) - rot);
}
rotateSprite(StationaryPageMask, (flipDirection * 45) - rot );
rotateSprite(FlippingPageMask, (flipDirection * 45) - rot);
if(Percentage == 0 && useShadows)
{
FlippingPageBorder.x = FlippingPageBitmap.x;
FlippingPageBorder.y = FlippingPageBitmap.y;
FlippingPageBorder.width = FlippingPageBitmap.bitmapData.width;
FlippingPageBorder.height = FlippingPageBitmap.bitmapData.height;
}
}
private function rotateSprite(spr:Sprite, degress:Number):void
{
var m:Matrix;
var x:Number;
var y:Number;
x = spr.x;
y = spr.y;
m = spr.transform.matrix;
m.a = 1;
m.b = 0;
m.c = 0;
m.d = 1;
m.rotate(clsSupport.ToRadians(degress));
m.tx = x;
m.ty = y;
spr.transform.matrix = m;
}
}
}
Can anyone tell me how to do this. Any help will be appreciated.
Impossible. if you want to use it in objective-c, must directly porting. Note that the page curl effect is built into iOS. To use the code on the iPhone using Air for iOS development.
Use a UIPageViewController to have this curl effect. Set the transitionStyle to UIPageViewControllerTransitionStylePageCurl or use the init-method – initWithTransitionStyle:navigationOrientation:options: .
Create instances of all the viewController you want use in put them into an array. This array is first argument of the setViewControllers:direction:animated:completion: method.