Fill polygon in unity 3d - unity3d

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; }
}

Related

How to fix Invalid worldAABB?

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?

2D procedural dungeon generation game

I am currently messing around with a procedural 2D game in unity. Below are the scripts i am using to generate the dungeon and wanted to know if there was anyway of specifying a standard starting room. I have prefab room built but would like to have a single prefab room players always start in.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class DungeonGeneration : MonoBehaviour {
[SerializeField]
private int numberOfRooms;
[SerializeField]
private int numberOfObstacles;
[SerializeField]
private Vector2Int[] possibleObstacleSizes;
[SerializeField]
private int numberOfEnemies;
[SerializeField]
private GameObject[] possibleEnemies;
[SerializeField]
private GameObject goalPrefab;
[SerializeField]
private TileBase obstacleTile;
private Room[,] rooms;
private Room currentRoom;
private static DungeonGeneration instance = null;
void Awake () {
if (instance == null) {
DontDestroyOnLoad (this.gameObject);
instance = this;
this.currentRoom = GenerateDungeon ();
} else {
string roomPrefabName = instance.currentRoom.PrefabName ();
GameObject roomObject = (GameObject) Instantiate (Resources.Load (roomPrefabName));
Tilemap tilemap = roomObject.GetComponentInChildren<Tilemap> ();
instance.currentRoom.AddPopulationToTilemap (tilemap, instance.obstacleTile);
Destroy (this.gameObject);
}
}
void Start () {
string roomPrefabName = this.currentRoom.PrefabName ();
GameObject roomObject = (GameObject) Instantiate (Resources.Load (roomPrefabName));
Tilemap tilemap = roomObject.GetComponentInChildren<Tilemap> ();
this.currentRoom.AddPopulationToTilemap (tilemap, this.obstacleTile);
}
private Room GenerateDungeon() {
int gridSize = 3 * numberOfRooms;
rooms = new Room[gridSize, gridSize];
Vector2Int initialRoomCoordinate = new Vector2Int ((gridSize / 2) - 1, (gridSize / 2) - 1);
Queue<Room> roomsToCreate = new Queue<Room> ();
roomsToCreate.Enqueue (new Room(initialRoomCoordinate.x, initialRoomCoordinate.y));
List<Room> createdRooms = new List<Room> ();
while (roomsToCreate.Count > 0 && createdRooms.Count < numberOfRooms) {
Room currentRoom = roomsToCreate.Dequeue ();
this.rooms [currentRoom.roomCoordinate.x, currentRoom.roomCoordinate.y] = currentRoom;
createdRooms.Add (currentRoom);
AddNeighbors (currentRoom, roomsToCreate);
}
int maximumDistanceToInitialRoom = 0;
Room finalRoom = null;
foreach (Room room in createdRooms) {
List<Vector2Int> neighborCoordinates = room.NeighborCoordinates ();
foreach (Vector2Int coordinate in neighborCoordinates) {
Room neighbor = this.rooms [coordinate.x, coordinate.y];
if (neighbor != null) {
room.Connect (neighbor);
}
}
room.PopulateObstacles (this.numberOfObstacles, this.possibleObstacleSizes);
room.PopulatePrefabs (this.numberOfEnemies, this.possibleEnemies);
int distanceToInitialRoom = Mathf.Abs (room.roomCoordinate.x - initialRoomCoordinate.x) + Mathf.Abs(room.roomCoordinate.y - initialRoomCoordinate.y);
if (distanceToInitialRoom > maximumDistanceToInitialRoom) {
maximumDistanceToInitialRoom = distanceToInitialRoom;
finalRoom = room;
}
}
GameObject[] goalPrefabs = { this.goalPrefab };
finalRoom.PopulatePrefabs(1, goalPrefabs);
return this.rooms [initialRoomCoordinate.x, initialRoomCoordinate.y];
}
private void AddNeighbors(Room currentRoom, Queue<Room> roomsToCreate) {
List<Vector2Int> neighborCoordinates = currentRoom.NeighborCoordinates ();
List<Vector2Int> availableNeighbors = new List<Vector2Int> ();
foreach (Vector2Int coordinate in neighborCoordinates) {
if (this.rooms[coordinate.x, coordinate.y] == null) {
availableNeighbors.Add (coordinate);
}
}
int numberOfNeighbors = (int)Random.Range (1, availableNeighbors.Count);
for (int neighborIndex = 0; neighborIndex < numberOfNeighbors; neighborIndex++) {
float randomNumber = Random.value;
float roomFrac = 1f / (float)availableNeighbors.Count;
Vector2Int chosenNeighbor = new Vector2Int(0, 0);
foreach (Vector2Int coordinate in availableNeighbors) {
if (randomNumber < roomFrac) {
chosenNeighbor = coordinate;
break;
} else {
roomFrac += 1f / (float)availableNeighbors.Count;
}
}
roomsToCreate.Enqueue (new Room(chosenNeighbor));
availableNeighbors.Remove (chosenNeighbor);
}
}
private void PrintGrid() {
for (int rowIndex = 0; rowIndex < this.rooms.GetLength (1); rowIndex++) {
string row = "";
for (int columnIndex = 0; columnIndex < this.rooms.GetLength (0); columnIndex++) {
if (this.rooms [columnIndex, rowIndex] == null) {
row += "X";
} else {
row += "R";
}
}
Debug.Log (row);
}
}
public void MoveToRoom(Room room) {
this.currentRoom = room;
}
public Room CurrentRoom() {
return this.currentRoom;
}
public void ResetDungeon() {
this.currentRoom = GenerateDungeon ();
}
}
and
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class Room
{
public Vector2Int roomCoordinate;
public Dictionary<string, Room> neighbors;
private string[,] population;
private Dictionary<string, GameObject> name2Prefab;
public Room (int xCoordinate, int yCoordinate)
{
this.roomCoordinate = new Vector2Int (xCoordinate, yCoordinate);
this.neighbors = new Dictionary<string, Room> ();
this.population = new string[18, 10];
for (int xIndex = 0; xIndex < 18; xIndex += 1) {
for (int yIndex = 0; yIndex < 10; yIndex += 1) {
this.population [xIndex, yIndex] = "";
}
}
this.population [8, 5] = "Player";
this.name2Prefab = new Dictionary<string, GameObject> ();
}
public Room (Vector2Int roomCoordinate)
{
this.roomCoordinate = roomCoordinate;
this.neighbors = new Dictionary<string, Room> ();
this.population = new string[18, 10];
for (int xIndex = 0; xIndex < 18; xIndex += 1) {
for (int yIndex = 0; yIndex < 10; yIndex += 1) {
this.population [xIndex, yIndex] = "";
}
}
this.population [8, 5] = "Player";
this.name2Prefab = new Dictionary<string, GameObject> ();
}
public List<Vector2Int> NeighborCoordinates () {
List<Vector2Int> neighborCoordinates = new List<Vector2Int> ();
neighborCoordinates.Add (new Vector2Int(this.roomCoordinate.x, this.roomCoordinate.y - 1));
neighborCoordinates.Add (new Vector2Int(this.roomCoordinate.x + 1, this.roomCoordinate.y));
neighborCoordinates.Add (new Vector2Int(this.roomCoordinate.x, this.roomCoordinate.y + 1));
neighborCoordinates.Add (new Vector2Int(this.roomCoordinate.x - 1, this.roomCoordinate.y));
return neighborCoordinates;
}
public void Connect (Room neighbor) {
string direction = "";
if (neighbor.roomCoordinate.y < this.roomCoordinate.y) {
direction = "N";
}
if (neighbor.roomCoordinate.x > this.roomCoordinate.x) {
direction = "E";
}
if (neighbor.roomCoordinate.y > this.roomCoordinate.y) {
direction = "S";
}
if (neighbor.roomCoordinate.x < this.roomCoordinate.x) {
direction = "W";
}
this.neighbors.Add (direction, neighbor);
}
public string PrefabName () {
string name = "Room_";
foreach (KeyValuePair<string, Room> neighborPair in neighbors) {
name += neighborPair.Key;
}
return name;
}
public Room Neighbor (string direction) {
return this.neighbors [direction];
}
public void PopulateObstacles (int numberOfObstacles, Vector2Int[] possibleSizes) {
for (int obstacleIndex = 0; obstacleIndex < numberOfObstacles; obstacleIndex += 1) {
int sizeIndex = Random.Range (0, possibleSizes.Length);
Vector2Int regionSize = possibleSizes [sizeIndex];
List<Vector2Int> region = FindFreeRegion (regionSize);
foreach (Vector2Int coordinate in region) {
this.population [coordinate.x, coordinate.y] = "Obstacle";
}
}
}
public void PopulatePrefabs (int numberOfPrefabs, GameObject[] possiblePrefabs) {
for (int prefabIndex = 0; prefabIndex < numberOfPrefabs; prefabIndex += 1) {
int choiceIndex = Random.Range (0, possiblePrefabs.Length);
GameObject prefab = possiblePrefabs [choiceIndex];
List<Vector2Int> region = FindFreeRegion (new Vector2Int(1, 1));
this.population [region[0].x, region[0].y] = prefab.name;
this.name2Prefab [prefab.name] = prefab;
}
}
private List<Vector2Int> FindFreeRegion (Vector2Int sizeInTiles) {
List<Vector2Int> region = new List<Vector2Int>();
do {
region.Clear();
Vector2Int centerTile = new Vector2Int(UnityEngine.Random.Range(2, 18 - 3), UnityEngine.Random.Range(2, 10 - 3));
region.Add(centerTile);
int initialXCoordinate = (centerTile.x - (int)Mathf.Floor(sizeInTiles.x / 2));
int initialYCoordinate = (centerTile.y - (int)Mathf.Floor(sizeInTiles.y / 2));
for (int xCoordinate = initialXCoordinate; xCoordinate < initialXCoordinate + sizeInTiles.x; xCoordinate += 1) {
for (int yCoordinate = initialYCoordinate; yCoordinate < initialYCoordinate + sizeInTiles.y; yCoordinate += 1) {
region.Add(new Vector2Int(xCoordinate, yCoordinate));
}
}
} while(!IsFree (region));
return region;
}
private bool IsFree (List<Vector2Int> region) {
foreach (Vector2Int tile in region) {
if (this.population [tile.x, tile.y] != "") {
return false;
}
}
return true;
}
public void AddPopulationToTilemap (Tilemap tilemap, TileBase obstacleTile) {
for (int xIndex = 0; xIndex < 18; xIndex += 1) {
for (int yIndex = 0; yIndex < 10; yIndex += 1) {
if (this.population [xIndex, yIndex] == "Obstacle") {
tilemap.SetTile (new Vector3Int (xIndex - 9, yIndex - 5, 0), obstacleTile);
} else if (this.population [xIndex, yIndex] != "" && this.population [xIndex, yIndex] != "Player") {
GameObject prefab = GameObject.Instantiate (this.name2Prefab[this.population [xIndex, yIndex]]);
prefab.transform.position = new Vector2 (xIndex - 9 + 0.5f, yIndex - 5 + 0.5f);
}
}
}
}
}
any help would be awesome even if you can point me in the direction to a how to.
Nice procedural dungeon generator! Just as a suggestion, could you cache the first room at the beginning when you are generating the dungeon? Then you can grab the initialRoomForPlayerSpawn coordinates/ position as a reference point for the character placement.
Room initialRoomForPlayerSpawn = null;
while (roomsToCreate.Count > 0 && createdRooms.Count < numberOfRooms) {
Room currentRoom = roomsToCreate.Dequeue ();
this.rooms [currentRoom.roomCoordinate.x, currentRoom.roomCoordinate.y] = currentRoom;
createdRooms.Add (currentRoom);
AddNeighbors (currentRoom, roomsToCreate);
/* Cache First Room */
if(createdRooms != null && createdRooms.Count <= 1) {
initialRoomForPlayerSpawn = currentRoom;
}
}

Unity3D : How to hide touchscreen keyboard when i select inputfile and inputfield still focus

I've had this problem for a long time. I want to hide touchscreen keyboard when I select inputfile and inputfield still focus. I don't need touchscreen keyboard but I need carretpostion and focus on inputfield(application like calculator).
Thank you everyone for the answer. I solved the problem by custom inputfield. I disable touchscreen keyboard and get carretpostion by OnPointerUp .
code :
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class InputFieldWithOutKeyboard : InputField
{
protected override void Start()
{
keyboardType = (TouchScreenKeyboardType)(-1);
}
public override void OnPointerDown(UnityEngine.EventSystems.PointerEventData eventData)
{
base.OnPointerDown(eventData);
}
public override void OnPointerUp(PointerEventData eventData)
{
Vector2 mPos;
RectTransformUtility.ScreenPointToLocalPointInRectangle(textComponent.rectTransform, eventData.position, eventData.pressEventCamera, out mPos);
Vector2 cPos = GetLocalCaretPosition();
int pos = GetCharacterIndexFromPosition(mPos);
Debug.Log("pos = " + pos);
GameObject.FindWithTag("canvas").GetComponent<Calculator>().carretPostion = pos;
GameObject.FindWithTag("canvas").GetComponent<Calculator>().carretVector = mPos;
base.OnPointerUp(eventData);
}
public Vector2 GetLocalCaretPosition()
{
// if (isFocused)
// {
TextGenerator gen = m_TextComponent.cachedTextGenerator;
UICharInfo charInfo = gen.characters[caretPosition];
float x = (charInfo.cursorPos.x + charInfo.charWidth) / m_TextComponent.pixelsPerUnit;
float y = (charInfo.cursorPos.y) / m_TextComponent.pixelsPerUnit;
Debug.Log("x=" + x + "y=" + y);
return new Vector2(x, y);
// }
// else
// return new Vector2(0f, 0f);
}
private int GetCharacterIndexFromPosition(Vector2 pos)
{
TextGenerator gen = m_TextComponent.cachedTextGenerator;
if (gen.lineCount == 0)
return 0;
int line = GetUnclampedCharacterLineFromPosition(pos, gen);
if (line < 0)
return 0;
if (line >= gen.lineCount)
return gen.characterCountVisible;
int startCharIndex = gen.lines[line].startCharIdx;
int endCharIndex = GetLineEndPosition(gen, line);
for (int i = startCharIndex; i < endCharIndex; i++)
{
if (i >= gen.characterCountVisible)
break;
UICharInfo charInfo = gen.characters[i];
Vector2 charPos = charInfo.cursorPos / m_TextComponent.pixelsPerUnit;
float distToCharStart = pos.x - charPos.x;
float distToCharEnd = charPos.x + (charInfo.charWidth / m_TextComponent.pixelsPerUnit) - pos.x;
if (distToCharStart < distToCharEnd)
return i;
}
return endCharIndex;
}
private int GetUnclampedCharacterLineFromPosition(Vector2 pos, TextGenerator generator)
{
// transform y to local scale
float y = pos.y * m_TextComponent.pixelsPerUnit;
float lastBottomY = 0.0f;
for (int i = 0; i < generator.lineCount; ++i)
{
float topY = generator.lines[i].topY;
float bottomY = topY - generator.lines[i].height;
// pos is somewhere in the leading above this line
if (y > topY)
{
// determine which line we're closer to
float leading = topY - lastBottomY;
if (y > topY - 0.5f * leading)
return i - 1;
else
return i;
}
if (y > bottomY)
return i;
lastBottomY = bottomY;
}
// Position is after last line.
return generator.lineCount;
}
private static int GetLineEndPosition(TextGenerator gen, int line)
{
line = Mathf.Max(line, 0);
if (line + 1 < gen.lines.Count)
return gen.lines[line + 1].startCharIdx - 1;
return gen.characterCountVisible;
}
}
You can use something like this
TouchScreenKeyboard keyboard;
void Update()
{
if (keyboard != null)
{
if (Input.deviceOrientation == DeviceOrientation.FaceDown)
keyboard.active = false;
if (Input.deviceOrientation == DeviceOrientation.FaceUp)
keyboard.active = true;
}
}
it will retrieve the TouchScreenKeyboard and after that, you can active or deactive it as you want.

My Program Creates 1 Ball not 2

I made a program that creates a frame and then creates 2 balls and moves them around seperately, my problem is that somehow the first or second ball is getting the coordinates of the other, and therefore are being painted on each other, sorry for the bad indentation this is my first time posting a question .
Main Class:
public class Game extends JPanel {
Ball ball01 = new Ball();
Ball ball02 = new Ball();
int ball01x = 0,ball01y = 0,ball02x = 0,ball02y = 0;
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.fillOval(ball01x, ball01y, 10, 10);
g2d.setColor(Color.RED);
g2d.fillOval(ball02x, ball02y, 10, 10);
}
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("Sample Frame");
Game game = new Game();
frame.add(game);
frame.setSize(400, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.createBalls();
while (true) {
game.getCoords();
game.updateBalls();
game.repaint();
System.out.println("Ball01 x: " + game.ball01x + " Ball02 x " + game.ball02x);
Thread.sleep(10);
}
}
public void getCoords(){
ball01x = ball01.getX();
ball01y = ball01.getY();
ball02x = ball02.getX();
ball02y = ball02.getY();
}
public void createBalls(){
ball01.create(300,300);
ball02.create(50,20);
}
public void updateBalls(){
ball01.Ball();
ball02.Ball();
}
}
Ball Class:
public class Ball{
private static int x;
private static int y;
private static int xSize = 30;
private static int ySize = 30;
static boolean xright = true,ydown = true;
static boolean grow = false;
public void Ball(){
this.moveBall();
this.ballSize();
}
public void create(int startX, int startY){
this.x = startX;
this.y = startY;
}
private void moveBall() {
if(this.x >= 370){
xright = false;
}
if(this.x <= 0){
xright = true;
}
if(this.y >= 370){
ydown = false;
}
if(this.y < 0){
ydown = true;
}
if(xright == true){
this.x = this.x + 1;
}else if (xright == false){
this.x = this.x - 1;
}
if(ydown == true){
this.y = this.y + 1;
}else if (ydown == false){
this.y = this.y - 1;
}
}
private void ballSize(){
if (xSize <= 5 && ySize <= 5){
grow = true;
}else if (xSize >= 10 && ySize >= 10){
grow = false;
}
if (grow == true){
xSize = xSize + 1;
ySize = ySize + 1;
//System.out.println("Debug");
}else if (grow == false){
xSize--;
ySize--;
//System.out.println("Debug");
}
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}

unity 4.5.1 2D player file faulty gravity ....( really aggravating)

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.