Create shapes in android with unity - c#

I am trying to create custom shapes in unity with free hand but i am getting very thick shapes Like this
I am using this code
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class DrawLine : MonoBehaviour
{
public Text toshow;
private LineRenderer line;
private bool isMousePressed;
public List<Vector3> pointsList;
private Vector3 mousePos;
// Structure for line points
struct myLine
{
public Vector3 StartPoint;
public Vector3 EndPoint;
};
// -----------------------------------
void Awake ()
{
// Create line renderer component and set its property
line = gameObject.AddComponent<LineRenderer> ();
line.material = new Material (Shader.Find ("Particles/Additive"));
line.SetVertexCount (0);
line.SetWidth (0.1f, 0.1f);
line.SetColors (Color.green, Color.green);
line.useWorldSpace = true;
isMousePressed = false;
pointsList = new List<Vector3> ();
// renderer.material.SetTextureOffset(
}
// Following method adds collider to created line
private void addColliderToLine(Vector3 startPos, Vector3 endPos)
{
BoxCollider col = new GameObject("Collider").AddComponent<BoxCollider> ();
col.gameObject.tag = "Box";
col.transform.parent = line.transform; // Collider is added as child object of line
float lineLength = Vector3.Distance (startPos, endPos); // length of line
col.size = new Vector3 (lineLength, 0.1f, 1f); // size of collider is set where X is length of line, Y is width of line, Z will be set as per requirement
Vector3 midPoint = (startPos + endPos)/2;
col.transform.position = midPoint; // setting position of collider object
// Following lines calculate the angle between startPos and endPos
float angle = (Mathf.Abs (startPos.y - endPos.y) / Mathf.Abs (startPos.x - endPos.x));
if((startPos.y<endPos.y && startPos.x>endPos.x) || (endPos.y<startPos.y && endPos.x>startPos.x))
{
angle*=-1;
}
angle = Mathf.Rad2Deg * Mathf.Atan (angle);
col.transform.Rotate (0, 0, angle);
}
void createCollider(){
for (int i=0; i < pointsList.Count - 1; i++) {
addColliderToLine(pointsList[i],pointsList[i+1]);
}
}
public void MouseDrag(){
#if UNITY_ANDROID
Vector2 touchPos = Input.touches[0].position;
mousePos = Camera.main.ScreenToWorldPoint (new Vector3(touchPos.x, touchPos.y, 0));
mousePos.z = 0;
if (!pointsList.Contains (mousePos)) {
pointsList.Add (mousePos);
line.SetVertexCount (pointsList.Count);
line.SetPosition (pointsList.Count - 1, (Vector3)pointsList [pointsList.Count - 1]);
}
#endif
}
public void MouseBeginDrag(){
isMousePressed = true;
line.SetVertexCount (0);
GameObject[] ob = GameObject.FindGameObjectsWithTag("Box");
for(int i=0; i<ob.Length; i++){
Destroy(ob[i]);
}
pointsList.RemoveRange (0, pointsList.Count);
line.SetColors (Color.green, Color.green);
}
public void MouseFinishDrag(){
createCollider();
isMousePressed = false;
}
// -----------------------------------
void Update ()
{
}
}
Please Help me to decrease the width of a line. I am not able to decrease the width of a line. Please help me

Related

LineRender | collision himself with raycast2D

i build game with line that you can control his movement.
every few seconeds the line create hole for the player can move through them.
look picture:
enter image description here
now in my code you can see the playerMovement, createLine and drawLine.
i draw the line By player location and every few seconeds i stop draw to millie seconed to create hole and than draw new line.
my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DrawLineNisayon : MonoBehaviour
{
[SerializeField] private GameObject linePrefab;
LineRenderer lineRenderer;
public GameObject currentLine;
private bool createHole = false;
private bool drawLine = false;
float rotZ = 0f;
public float speedMovement = 3f;
public float speedRotation = 6f;
public float timingCreateHoles = 2f;
public float widthHoles = 0.2f;
public EdgeCollider2D edgeCollider2D;
public List<Vector2> posLine;
void Start()
{
CreateLine();
}
void Update()
{
PlayerMovement(speedMovement);
DrawLine();
}
private void CreateLine()
{
currentLine = Instantiate(linePrefab, Vector3.zero, Quaternion.identity);
lineRenderer = currentLine.GetComponent<LineRenderer>();
edgeCollider2D = currentLine.GetComponent<EdgeCollider2D>();
posLine.Clear();
posLine.Add(transform.position);
posLine.Add(transform.position);
lineRenderer.SetPosition(0, posLine[0]);
lineRenderer.SetPosition(1, posLine[1]);
edgeCollider2D.points = posLine.ToArray();
}
private void DrawLine()
{
if(!drawLine)
{
posLine.Add(transform.position);
lineRenderer.positionCount++;
lineRenderer.SetPosition(lineRenderer.positionCount - 1, transform.position);
edgeCollider2D.points = posLine.ToArray();
RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.right, 1f);
Debug.DrawRay(posLine[lineRenderer.positionCount - 1], transform.right);
if(createHole == false){
StartCoroutine(DrawHole(timingCreateHoles));
createHole = true;
}
}
}
private IEnumerator DrawHole(float timingCreateHoles)
{
yield return new WaitForSeconds(timingCreateHoles);
drawLine = true;
StartCoroutine(DrawLine(widthHoles));
}
private IEnumerator DrawLine(float widthHoles)
{
yield return new WaitForSeconds(widthHoles);
CreateLine();
drawLine = false;
createHole = false;
}
private void PlayerMovement(float speed)
{
transform.Translate(Vector3.right * speed * Time.deltaTime);
if(Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.A))
{
transform.Rotate(0f, 0f, rotZ);
rotZ = speedRotation;
}
if (!Input.GetKey(KeyCode.D) && Input.GetKey(KeyCode.A))
{
transform.Rotate(0f, 0f, rotZ);
rotZ = -speedRotation;
}
}
}
so what is my problem? i try to create raycast to check collision with the line himself like the game "snake". i tryed to create raycast in function "DrawLine" and i havnt idea how to do that.
my line built by list of vector2 like you can see in my code, its say that i need to compare vector to vector and i dont know how...
*i try collision with the last index in line, not with the circle in the picture.

Instantiate Game Object floating in air

I'm making a tower defense game in Unity 3D C#. The goal is for players to place objects in a grid (grid code below). I'm having trouble getting the "Corner" object to get placed on the ground, it's just appearing anywhere in the Y axis that I click. I'm confused because I'm using the same exact script for a different item and it's working fine (I just changed out the words "wall" for "corner"). The only difference between the items is that one is a straight line and one is an L shape (I did this through making two cubes, combining them, and putting them as a child Empty game object called "corner"). Any ideas?
using UnityEngine;
public class Grid : MonoBehaviour
{
[SerializeField]
private float size = 1f;
public Vector3 GetNearestPointOnGrid(Vector3 position)
{
position -= transform.position;
int xCount = Mathf.RoundToInt(position.x / size);
int yCount = Mathf.RoundToInt(position.y / size);
int zCount = Mathf.RoundToInt(position.z / size);
Vector3 result = new Vector3(
(float)xCount * size,
(float)yCount * size,
(float)zCount * size);
result += transform.position;
return result;
}
private void OnDrawGizmos()
{
Gizmos.color = Color.yellow;
for (float x = 0; x < 40; x += size)
{
for (float z = 0; z < 40; z += size)
{
var point = GetNearestPointOnGrid(new Vector3(x, 0f, z));
Gizmos.DrawSphere(point, 0.1f);
}
}
}
}
CornerPlacer:
using UnityEngine;
public class CornerPlacer : MonoBehaviour
{
private Grid grid;
public GameObject corner;
public bool placeCornerMode;
private void Awake()
{
grid = FindObjectOfType<Grid>();
}
void Update()
{
if (placeCornerMode)
{
GetItemsCorner();
}
}
void GetItemsCorner()
{
if (Input.GetMouseButtonDown(0))
{
RaycastHit hitInfo;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hitInfo))
{
PlaceCornerNear(hitInfo.point);
placeCornerMode = false;
}
}
}
private void PlaceCornerNear(Vector3 clickPoint)
{
var finalPosition = grid.GetNearestPointOnGrid(clickPoint);
Instantiate(corner, finalPosition, Quaternion.identity);
}
public void CornerModeOn()
{
placeCornerMode = true;
}
}

Unity3d How to make line start from mouse position on camera

Currently, the line starts where I click and locks to those coordinates.
However, I want the line to start where I click on the screen and not start moving until I let go of the mouse.
(Game currently has a ball falling).
using UnityEngine;
using System.Collections;
public class TrailCollider : MonoBehaviour
{
private LineRenderer line; // Reference to LineRenderer
private Vector3 mousePos;
public PhysicsMaterial2D phys;
private Vector3 startPos; // Start position of line
private Vector3 endPos; // End position of line
void Update ()
{
// On mouse down new line will be created
if(Input.GetMouseButtonDown(0))
{
if(line == null)
createLine();
mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mousePos.z = 0;
line.SetPosition(0,mousePos);
line.SetPosition(1,mousePos);
startPos = mousePos;
}
else if(Input.GetMouseButtonUp(0))
{
if(line)
{
mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mousePos.z = 0;
line.SetPosition(1,mousePos);
endPos = mousePos;
addColliderToLine();
line = null;
}
}
else if(Input.GetMouseButton(0))
{
if(line)
{
mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mousePos.z = 0;
line.SetPosition(1,mousePos);
}
}
}
// Following method creates line runtime using Line Renderer component
private void createLine()
{
line = new GameObject("Line").AddComponent<LineRenderer>();
line.material = new Material(Shader.Find("Diffuse"));
line.SetVertexCount(2);
line.SetWidth(0.1f,0.1f);
line.SetColors(Color.black, Color.black);
line.useWorldSpace = true;
}
// Following method adds collider to created line
private void addColliderToLine()
{
BoxCollider2D col = new GameObject("Collider").AddComponent<BoxCollider2D> ();
col.transform.parent = line.transform; // Collider is added as child object of line
col.sharedMaterial = phys;
float lineLength = Vector3.Distance (startPos, endPos); // length of line
col.size = new Vector3 (lineLength, 0.1f, 1f); // size of collider is set where X is length of line, Y is width of line, Z will be set as per requirement
Vector3 midPoint = (startPos + endPos)/2;
col.transform.position = midPoint; // setting position of collider object
// Following lines calculate the angle between startPos and endPos
float angle = (Mathf.Abs (startPos.y - endPos.y) / Mathf.Abs (startPos.x - endPos.x));
if((startPos.y<endPos.y && startPos.x>endPos.x) || (endPos.y<startPos.y && endPos.x>startPos.x))
{
angle*=-1;
}
angle = Mathf.Rad2Deg * Mathf.Atan (angle);
col.transform.Rotate (0, 0, angle);
}
}

touch control to move cube (in an array that generates them) left and right

I am moving an object that consists of two cubes: left and right. These cubes are randomly generated on the y-axis upwards.
I am able to move them left and right with no problem, however, when I move one of the cubes left or right they all move.
How am I able to only move one of the cubes when touched only left or right rather than all of them? Here is my code below:
Generate cubes code:
public Transform block;
public Transform player;
private float objectSpawnedTo = 5.0f;
public static float distanceBetweenObjects = 5.0f;
private float nextCheck = 0.0f;
private ArrayList objects = new ArrayList();
void Start () {
maintenance(0.0f);
}
void Update () {
float playerX = player.position.y;
if(playerX > nextCheck)
{
maintenance(playerX);
}
}
private void maintenance(float playerX)
{
nextCheck = playerX + 30;
for (int i = objects.Count-1; i >= 0; i--)
{
Transform blck = (Transform)objects[i];
if(blck.position.y < (transform.position.y - 30))
{
Destroy(blck.gameObject);
objects.RemoveAt(i);
}
}
spawnObjects(5);
}
private void spawnObjects(int howMany)
{
float spawnX = objectSpawnedTo;
for(int i = 0; i<howMany; i++)
{
Vector3 pos = new Vector3(-3.5f,spawnX, 0);
//float firstRandom = Random.Range(-6.0f, 1.0f);
Transform blck = (Transform)Instantiate(block, pos, Quaternion.identity);
//blck.localScale+=new Vector3(firstRandom*2,0,0);
objects.Add(blck);
//pos = new Vector3(0,spawnX, 0);
//blck = (Transform)Instantiate(block, pos, Quaternion.identity);
//blck.localScale +=new Vector3((8.6f-firstRandom)*2,0,0);
//objects.Add(blck);
spawnX = spawnX + distanceBetweenObjects;
}
objectSpawnedTo = spawnX;
}
}
Cube-control code:
public float speed = 5;
// Use this for initialization
void Start () {
}
void Update() {
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved) {
// Get movement of the finger since last frame
Vector3 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
// Move object across XY plane
transform.Translate(touchDeltaPosition.x * speed, 0, 0);
Vector3 boundaryVector = transform.position;
boundaryVector.x = Mathf.Clamp (boundaryVector.x, -5.5f, -2.8f);
transform.position = boundaryVector;
}
}
}
The problem is your cube-control code has no condition in it about which cube is selected : you simply wait for Input.touchCount to be > 0 and then move the cube. So all the cube having this script will move.
I think what you need to do is a raycast to check which cube has been "touched" and then only move it if raycast is successful :
[SerializeField]
private float speed = 0.5f;
private int MAX_TOUCH_COUNT = 5;
private bool[] touched;
protected void Start()
{
touched = new bool[MAX_TOUCH_COUNT];
}
void Update()
{
if (Input.touchCount > 0)
{
for(int i = 0; i < (Input.touchCount <= MAX_TOUCH_COUNT ? Input.touchCount : MAX_TOUCH_COUNT); i++)
{
if(touched[i] && Input.GetTouch(i).phase == TouchPhase.Ended)
{
touched[i] = false;
}
else if (!touched[i] && Input.GetTouch(i).phase == TouchPhase.Began)
{
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
if (hitInfo.transform.GetComponentInChildren<*YOUR_CUBE_CONTROL_CLASS_NAME*>() == this)
{
touched[i] = true;
}
}
}
else if (touched[i] && Input.GetTouch(i).phase == TouchPhase.Moved)
{
// Get movement of the finger since last frame
Vector3 touchDeltaPosition = Input.GetTouch(i).deltaPosition;
// Move object across XY plane
transform.Translate(touchDeltaPosition.x * speed, 0, 0);
Vector3 boundaryVector = transform.position;
boundaryVector.x = Mathf.Clamp (boundaryVector.x, -5.5f, -2.8f);
transform.position = boundaryVector;
}
}
else
{
touched = false;
}
}
}
Hope this help,

Set appropriate Collider type for each Mesh that gets created

I'm generating a bunch of basic sphere and capsule mesh objects at runtime in a 3D fractal-based piece I'm working on, and I'm stuck on how to apply the appropriate Collider type when each object gets created.
My script randomly selects from either spheres or capsules and arranges them based on a range of orientation possibilities. I need help on how to assign the appropriate Collider when each mesh gets created.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class BuildFractal : MonoBehaviour
{
public Mesh[] meshes;
public Material material;
public Material[,] materials;
private Rigidbody rb;
public int maxDepth; // max children depth
private int depth;
public float childScale; // set scale of child objects
public float spawnProbability; // determine whether a branch is created or not
public float maxRotationSpeed; // set maximium rotation speed
private float rotationSpeed;
public float maxTwist;
public Text positionText;
public int objectMass;
// Create arrays for direction and orientation data
private static Vector3[] childDirections = {
Vector3.up,
Vector3.right,
Vector3.left,
Vector3.forward,
Vector3.back,
// Vector3.down
};
private static Quaternion[] childOrientations = {
Quaternion.identity,
Quaternion.Euler(0f, 0f, -90f),
Quaternion.Euler(0f, 0f, 90f),
Quaternion.Euler(90f, 0f, 0f),
Quaternion.Euler(-90f, 0f, 0f),
// Quaternion.Euler(180f, 0f, 0f)
};
private void Start ()
{
Rigidbody rb;
rotationSpeed = Random.Range(-maxRotationSpeed, maxRotationSpeed);
transform.Rotate(Random.Range(-maxTwist, maxTwist), 0f, 0f);
if (materials == null)
{
InitializeMaterials();
}
// Select from random range of meshes
gameObject.AddComponent<MeshFilter>().mesh = meshes[Random.Range(0, meshes.Length)];
// Select from random range of colors
gameObject.AddComponent<MeshRenderer>().material = materials[depth, Random.Range(0, 2)];
// Add Rigigbody to each object
rb = gameObject.AddComponent<Rigidbody>();
rb.useGravity = false;
rb.mass = objectMass;
// Create Fractal Children
if (depth < maxDepth)
{
StartCoroutine(CreateChildren());
}
}
private void Update ()
{
transform.Rotate(0f, rotationSpeed * Time.deltaTime, 0f);
}
private void Initialize (BuildFractal parent, int childIndex)
{
maxRotationSpeed = parent.maxRotationSpeed;
// copy mesh and material references from parent object
meshes = parent.meshes;
materials = parent.materials;
maxTwist = parent.maxTwist;
// set depth and scale based on variables defined in parent
maxDepth = parent.maxDepth;
depth = parent.depth + 1;
childScale = parent.childScale;
transform.parent = parent.transform; // set child transform to parent
// transform.localScale = Vector3.one * childScale;
transform.localScale = Vector3.one * Random.Range(childScale / 10, childScale * 1);
transform.localPosition = childDirections[childIndex] * (Random.Range((0.1f + 0.1f * childScale),(0.9f + 0.9f * childScale)));
transform.localRotation = childOrientations[childIndex];
spawnProbability = parent.spawnProbability;
}
private void InitializeMaterials ()
{
materials = new Material[maxDepth + 1, 2];
for (int i = 0; i <= maxDepth; i++)
{
float t = i / (maxDepth - 1f);
t *= t;
// Create a 2D array to hold color progressions
materials[i, 0] = new Material(material);
materials[i, 0].color = Color.Lerp(Color.gray, Color.white, t);
materials[i, 1] = new Material(material);
materials[i, 1].color = Color.Lerp(Color.white, Color.cyan, t);
}
// materials[maxDepth, 0].color = Color.white;
materials[maxDepth, 1].color = Color.white;
}
private IEnumerator CreateChildren ()
{
for (int i = 0; i < childDirections.Length; i++)
{
if (Random.value < spawnProbability)
{
yield return new WaitForSeconds(Random.Range(0.1f, 1.5f));
new GameObject("Fractal Child").AddComponent<BuildFractal>().Initialize(this, i);
}
}
}
/*void OnCollisionEnter(Collision col)
{
if(col.gameObject.name == "Fractal Child")
{
Destroy(this.gameObject);
}
}*/
}
Add a mesh collider after you instantiate and set the same mesh, job done!
http://docs.unity3d.com/ScriptReference/MeshCollider.html
that should sort it out programmatically

Categories