In project I'm currently working on I need to adjust legs position to ground when character stands on a ramp, to avoid look like any of his legs floating above the ground. I think i need to do it somewhere in this method, but I can't figure out how.
public void SetCharacterState(string state)
{
currentState = state;
if (state.Equals("Idle") && once != 0)
{
SetAnimation(idle, true, 1f);
print("Correcting legs position");
once = 0;
}
if (state.Equals("Run") && once != 1)
{
SetAnimation(run, true, 1f);
once = 1;
}
if (state.Equals("jumpFrom_Idle") && once != 2)
{
SetAnimation(jumpFrom_Idle, false, 1f);
StartCoroutine(IE_jump());
canAnimationChange = false;
once = 2;
}
if (state.Equals("jumpFrom_Run") && once != 3)
{
SetAnimation(jumpFrom_Run, false, 1f);
StartCoroutine(IE_jump());
canAnimationChange = false;
once = 3;
}
if (state.Equals("freeFall") && once != 4)
{
SetAnimation(freeFall, true, 1f);
once = 4;
}
if (state.Equals("freeFall_Land") && once != 5)
{
SetAnimation(freeFall_Land, false, 1f);
StartCoroutine(IE_freeFall_Land());
controller.canJump = false;
canAnimationChange = false;
once = 5;
}
}
Any suggestions?
Related
I've been working on a project for the GMTK 2022 Game Jam recently, and I ran into a very strange problem. I have a dash that starts when you are moving and press space. It moves you in the direction of your velocity, then for a short time lets you move very quickly. It works perfectly fine in all cases, unless the direction you are moving is up and to the left, in which case, the if statement strangely won't trigger. I'm sure this is something idiotic, but I've been troubleshooting it for the last hour and it's been driving me insane.
// Update is called once per frame
void Update()
{
playerInputh = 0;
playerInputv = 0;
if (Input.GetKey("right"))
{
playerInputh = 1;
}
if (Input.GetKey("left"))
{
playerInputh = -1;
}
if (Input.GetKey("right") && Input.GetKey("left"))
{
playerInputh = 0;
}
if (Input.GetKey("up"))
{
playerInputv = 1;
}
if (Input.GetKey("down"))
{
playerInputv = -1;
}
if (Input.GetKey("up") && Input.GetKey("down"))
{
playerInputv = 0;
}
Vector2 screenPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
Vector2 mouseWorldPosition = Camera.main.ScreenToWorldPoint(screenPosition);
//This is the dash that isn't working:
if ((Input.GetKeyDown(/*"right shift"*/"space")) && (playerInputh != 0 || playerInputv != 0))
{
Debug.Log("Dash");
//Vector2 transform2dposition = new Vector2(transform.position.x, transform.position.y);
m_Rigidbody.AddForce((m_Rigidbody.velocity) * 500f);
wJumpTimer = airControlAfterJump;
speed = maxSpeed*3.5f;
StartCoroutine(Roll());
}
}
void FixedUpdate()
{
//no moving while jumping!!!
if (wJumpTimer > 0)
{
wJumpTimer -= 1;
}
else
{
wJumpTimer = 0;
}
//move
if (playerInputh != 0 && playerInputv != 0) //make diagonals no super sayan
{
playerInputh *= moveLimiter;
playerInputv *= moveLimiter;
one_h = playerInputh;//futureproof
one_v = playerInputv;
}
if ((playerInputh != 0 || playerInputv != 0) && speed < maxSpeed) //are we hitting the move buttons??
{
speed += acceleration;//accelerate
one_h = playerInputh;//futureproof
one_v = playerInputv;
}
else
{
if (speed > 0f) //are we getting off the ride
{
speed -= deceleration; //decelerate
}
else
{
speed = 0f; //no funny buisness
}
}
m_Rigidbody.velocity = new Vector2(one_h * speed, one_v * speed); //actually move
}
void SetFace(int diceNumb)
{
rndr.sprite = sprites[diceNumb];
}
IEnumerator Roll()
{
Random diceNumb = new Random();
rndr.sprite = sprites[diceNumb.Next(0,5)];
yield return new WaitForSeconds(0.125f);
rndr.sprite = sprites[diceNumb.Next(0, 5)];
yield return new WaitForSeconds(0.125f);
rndr.sprite = sprites[diceNumb.Next(0, 5)];
yield return new WaitForSeconds(0.125f);
rndr.sprite = sprites[diceNumb.Next(0, 5)];
yield return new WaitForSeconds(0.125f);
var newValue = diceNumb.Next(0, 5);
FaceValue = newValue + 1;
rndr.sprite = sprites[newValue];
}
How are your inputs setup? I am suspecting you have one key bound to multiple actions, like one key is set up as primary for an action and alternate for another action.
Personally I'd also stop using the assignment operators and increment instead. Instead of
playerInputh = 0;
if (Input.GetKey("right"))
{
playerInputh = 1;
}
if (Input.GetKey("left"))
{
playerInputh = -1;
}
if (Input.GetKey("right") && Input.GetKey("left"))
{
playerInputh = 0;
}
you can do
playerInputv = 0;
if (Input.GetKey("right"))
{
playerInputh += 1;
}
if (Input.GetKey("left"))
{
playerInputh += -1;
}
Net result is the same here - if you push both keys the result sums to zero, but the code is easier to read (IMO).
When you check things for key bindings also check alternates for space, because that's another one of the triggers you need to dash.
Here is my code:
void Update()
{
if (shipController.Mode == ShipController.ShipMode.Build)
{
var mouseInWorld = Camera.main.ScreenToWorldPoint(Mouse.current.position.ReadValue());
Debug.Log(mouseInWorld);
var mousePos = new Vector2(mouseInWorld.x, mouseInWorld.y);
var currentPos = new Vector2(transform.position.x, transform.position.y);
var posToTarget = mousePos - currentPos;
var oldPosToTarget = posToTarget;
var oldPos = currentPos;
var shotPastTargetOrExact = false;
var iter = 0;
while (!shotPastTargetOrExact)
{
iter++;
Debug.Log(iter);
oldPos = currentPos;
oldPosToTarget = posToTarget;
if (posToTarget == Vector2.zero) shotPastTargetOrExact = true;
if (Mathf.Abs(posToTarget.x) >= Mathf.Abs(posToTarget.y))
{
if (posToTarget.x > 0) currentPos = new Vector2(currentPos.x += blockdistance, currentPos.y);
else currentPos = new Vector2(currentPos.x -= blockdistance, currentPos.y);
}
else
{
if (posToTarget.y > 0) currentPos = new Vector2(currentPos.x, currentPos.y += blockdistance);
else currentPos = new Vector2(currentPos.x, currentPos.y -= blockdistance);
}
posToTarget = mousePos - currentPos;
if (posToTarget.sqrMagnitude > oldPosToTarget.sqrMagnitude)
{
shotPastTargetOrExact = true;
currentPos = oldPos;
}
}
if (currentSlot != null && currentSlot.CurrentItemDragAndDrop != null && currentSlot.CurrentItemDragAndDrop.Item != null)
{
var item = currentSlot.CurrentItemDragAndDrop.Item;
if (currentPlacementBlock == null)
{
currentPlacementBlock = Instantiate(item.BlockPrefab);
}
currentPlacementBlock.transform.localPosition = currentPos;
currentPlacementBlock.transform.rotation = shipController.transform.rotation;
}
else if (currentPlacementBlock != null)
{
Destroy(currentPlacementBlock);
currentPlacementBlock = null;
}
}
}
It crashes when I try to stop the game with the play button in the editor. It has also crashed when starting build mode (see shipController.Mode)
The script works as intended but crashes when stopping the game.
I loged the iterations to try and see if it was looping forever but it doesnt seem to be that as it always comes out with a small iter number in the console
I fixed it by checking if the mouse was in the window before going ahead and performing the rest of the update
bool IsMouseOverGameWindow { get { var mousePosition = Mouse.current.position.ReadValue(); return !(0 > mousePosition.x || 0 > mousePosition.y || Screen.width < mousePosition.x || Screen.height < mousePosition.y); } }
I have a problem with drag and drop on game. I want to block user if he is dragging the object from down to up in case they have sticks in same angles. if they dont so it is ok. But if they have even one stick in same direction so stick should go back to down to first position.
I am lost a bit. Can you help please :)
here is the code where I drag and drop also rotation...
Here on the pic generated stick group can fit only 1. and 3. places.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InputController : MonoBehaviour
{
float clickTime;
RaycastHit2D rayhit;
float smallestDistance = 1.5f;
int smallestId = 1;
public Transform[] nodes;
public LayerMask selectableObjLayerMask;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
clickTime = Time.time;
rayhit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, Mathf.Infinity, selectableObjLayerMask);
}
else if (Input.GetMouseButtonUp(0))
{
if (rayhit)
{
if (Time.time - clickTime < .2f)
{
Node node = rayhit.transform.GetComponent<Node>();
if (node != null)
{
for (int i = 0; i < node.sticks.Count; i++)
{
Vector3 newAngles = new Vector3(0, 0, (node.sticks[i].transform.localEulerAngles.z - 45));
newAngles.z = newAngles.z < 0 ? newAngles.z + 180 : newAngles.z;
newAngles.z = newAngles.z >180 ? newAngles.z - 180 : newAngles.z;
node.sticks[i].transform.localEulerAngles = newAngles;
node.sticks[i].degree = (int)newAngles.z;
Debug.Log(i + " = " + node.sticks[i].degree);
}
}
}
else
{
Node currNode = rayhit.transform.GetComponent<Node>();
if(currNode.isMoved == false)
{
smallestId = 0;
smallestDistance = 999;
for (int i = 0; i < nodes.Length; i++)
{
float distance = Vector2.Distance(rayhit.transform.position, nodes[i].transform.position);
if (smallestDistance > distance)
{
smallestDistance = distance;
smallestId = i;
Debug.Log("Obje : " + currNode);
}
}
rayhit.transform.position = nodes[smallestId].transform.position;
if (rayhit.transform.parent != nodes[smallestId].transform)
{
if (nodes[smallestId].transform.childCount > 0 && nodes[smallestId].transform != rayhit.transform.parent)
{
if (currNode != null)
{
for (int i = 0; i < currNode.sticks.Count; i++)
{
nodes[smallestId].transform.GetChild(0).GetComponent<Node>().sticks.Add(currNode.sticks[i]);
currNode.sticks[i].transform.SetParent(nodes[smallestId].transform.GetChild(0));
}
Destroy(rayhit.transform.gameObject);
}
}
else
{
if (currNode != null)
{
currNode.isMoved = true;
}
rayhit.transform.SetParent(nodes[smallestId].transform);
}
}
}
}
}
rayhit = new RaycastHit2D();
}
else if (Input.GetMouseButton(0))
{
if(rayhit.transform != null)
{
Node currNode = rayhit.transform.GetComponent<Node>();
if(currNode != null)
if (currNode.isMoved == false)
{
if (Time.time - clickTime >= 0.2f)
{
Vector2 newPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
rayhit.transform.position = newPos;
}
}
}
}
}
}
So I made this code in an effort to start making a script that generates bush objects in my scene randomly, however when in runs it only spawns the first bush. Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BushSpawner : MonoBehaviour
{
public GameObject bush;
private float x = 0f;
private float y = -.47f;
private float z = 0f;
private int bushCount = 0;
private Vector3 origPos;
private bool xPlus = false;
private bool xMinus = false;
private bool zPlus = false;
private bool zMinus = false;
// Use this for initialization
void Start()
{
SpawnBushes();
}
// Update is called once per frame
void Update()
{
}
void SpawnBushes()
{
Vector3 startPos = new Vector3(x, y, z);
Instantiate(bush, startPos, Quaternion.identity);
bushCount += 1;
while (bushCount < 100)
{
Vector3 checkPos = new Vector3(x, y, z);
Collider[] intersecting = Physics.OverlapSphere(checkPos, 1f);
if (intersecting.Length == 0)
{
//code to run if nothing is intersecting as the length is 0
Instantiate(bush, checkPos, Quaternion.identity);
bushCount += 1;
}
else
{
//code to run if something is intersecting it
RollPos();
}
}
}
void RollPos()
{
if (xPlus == true
&& xMinus == true
&& zPlus == true
&& zMinus == true)
{
int newRoll = Random.Range(1, 4);
if (newRoll == 1)
{
x += 10f;
}
else if (newRoll == 2)
{
x -= 10f;
}
else if (newRoll == 3)
{
z += 10f;
}
else if (newRoll == 4)
{
z -= 10f;
}
xPlus = false;
xMinus = false;
zPlus = false;
zMinus = false;
}
else
{
int roll = Random.Range(1, 4);
if (roll == 1)
{
if (xPlus == false)
{
x += 2f;
xPlus = true;
}
else
{
RollPos();
}
}
if (roll == 2)
{
if (xMinus == false)
{
x -= 2f;
xMinus = true;
}
else
{
RollPos();
}
}
if (roll == 3)
{
if (zPlus == false)
{
z += 2f;
zPlus = true;
}
else
{
RollPos();
}
}
if (roll == 4)
{
if (zMinus == false)
{
z -= 2f;
zMinus = true;
}
else
{
RollPos();
}
}
}
}
}
I tried putting SpawnBushes in Update to run while a bool is true then make it false when SpawnBushes is done, but that creates the first bush, then 99 other bushes in one random position next to it.
If someone can point me in the right direction or tell me I'm completely off-base I would appreciate it immensely!
Ron Beyer pointed out that I didn't have a large enough range in my Random.Range in RollPos(). Thanks again Ron!
I try to creacte some buildings in 2d, but it should not be touched with the other buildings.I have a
private GameObject building;
From Update i called function
buildFence(Vector2 nextPos)
where i create new building
And from this function i called function which must return boolean type
public bool canbuild()
{
//Debug.Log(building);
if (building.GetComponent<Rigidbody2D>().IsTouchingLayers(LayerMask.GetMask("Buildings")))
{
building.GetComponent<SpriteRenderer>().color = Color.red;
//Debug.Log("canb=false");
return false;
}
else {
building.GetComponent<SpriteRenderer>().color = Color.green;
return true;
}
}
but this function always return true. If i called the same function from Update,
everything works well.
All code here
void Update()
{
if (mode)
{
if (TEST)
{
if (!UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
{
if (Input.GetMouseButtonDown(0) && idBuilding != 0 && buildFlag)
{
buildFlag = false;
startpos = cam.ScreenToWorldPoint(Input.mousePosition);
if (idBuilding != 1)
{
building = (GameObject)Instantiate(buildings[idBuilding - 1], startpos, new Quaternion(0, 0, 0, 0));
building.GetComponent<Collider2D>().isTrigger = true;
canbuild();
}
else
{
}
}
if (Input.GetMouseButton(0) && idBuilding != 0)
{
if (idBuilding != 1)
{
Vector2 pos = cam.ScreenToWorldPoint(Input.mousePosition);
building.transform.position = pos;
canbuild();
}
else
{
buildFence(cam.ScreenToWorldPoint(Input.mousePosition));
if (!canbuild())
{
Debug.Log("succes");
}
}
}
if (Input.GetMouseButtonUp(0) && idBuilding != 0)
{
if (canbuild())
{
buildFlag = false;
Vector2 viewportPoint = Camera.main.WorldToViewportPoint(building.transform.position + new Vector3(2, 2, 0));
bAccept.anchorMin = viewportPoint;
bAccept.anchorMax = viewportPoint;
bAccept.gameObject.active = true;
}
else
{
Debug.Log("CantBuild");
Destroy(building);
buildFlag = true;
}
//building.GetComponent<Collider2D>().enabled = true;
}
}
}
else
{
}
}
}
void buildFence(Vector2 nextPos)
{
Vector2 delta = nextPos - startpos;
//Debug.Log("v2" + (nextPos - startpos));
//Debug.Log("v2.angle="+ Vector2.Angle(new Vector2(x, y), (nextPos - startpos)));
//Debug.Log("v2.angle=" +);
if (delta.magnitude >= 2.55 && canBuildNext)
{
if (delta.x < 0)
building = (GameObject)Instantiate(buildings[0], startpos, Quaternion.Euler(0, 0, Vector2.Angle(new Vector2(x, y), (nextPos - startpos))));
else
building = (GameObject)Instantiate(buildings[0], startpos, Quaternion.Euler(0, 0, -Vector2.Angle(new Vector2(x, y), (nextPos - startpos))));
building.GetComponent<Collider2D>().isTrigger = true;
canBuildNext = false;
}
if (!canBuildNext)
{
if (!canbuild(ref building))
{
Debug.Log("HERE");
if (delta.x < 0)
building.transform.rotation = Quaternion.Euler(0, 0, Vector2.Angle(new Vector2(x, y), (nextPos - startpos)));
else
building.transform.rotation = Quaternion.Euler(0, 0, -Vector2.Angle(new Vector2(x, y), (nextPos - startpos)));
}
else
{
startpos = nextPos;
//building.GetComponent<Collider2D>().isTrigger = false;
Zabor.Push(building);
canBuildNext = true;
}
}
}
public bool canbuild()
{
//Debug.Log(b);
//Debug.Log(building);
if (building.GetComponent<Rigidbody2D>().IsTouchingLayers(LayerMask.GetMask("Buildings")))
{
building.GetComponent<SpriteRenderer>().color = Color.red;
//Debug.Log("canb=false");
buildfail = false;
return false;
}
else {
building.GetComponent<SpriteRenderer>().color = Color.green;
buildfail = true;
return true;
}
}