I'm trying to recreate a dolphin dive type of feel, as of right now my character is a cube with no animation so I feel like the best way to do this would be to manually move the camera as if the character had just dolphin dived but every time I try to move the camera the entire player itself moves.
Code:
if (Input.GetKeyDown(KeyCode.C) && isSprinting) {
for (float i = 0; i <= 10; i++) {
var forceForward = 8f;
if (isGrounded == true && moveVertical != 0) {
_rgb.AddForce(fpsCam.transform.forward * forceForward);
for (float j = 0; j <= 10; j++) {
_camera.AddForce(Vector3.up * 3f);
}
}
}
}
if you need any more information let me know!
If you want a shortcut, you can make the camera gameobject a child of the player game object. This way it will move with the player.
Related
I have a spawn obstacles for a player, and when a game begins, obstacles appear in each other. I tried to solve this problem through the while and physics 2d cycle, but when I started the game, the Unity crashed.
And I also tried through Raycast2D to check when the beam collides with some kind of collider, and change its position. But ray a small didn't always work.
First way
while (!Physics.CheckBox(pos, BlotPref[1].transform.localScale))
{
pos = new Vector2(Random.Range(-1f, 1f), YPosSetter());
}
Second way
while (hit.collider == null)
{
transform.position = new Vector2(Random.Range(-1f, 1f), YPosSetter());
}
Spawner
private void SpawnerPaper()
{
for (int i = 0; i < PlaningSpawn; i++)
{
if (rndType <= _dbPaperSpawn)
{
var blot = Instantiate(BlotPref[Random.Range(0, BlotPref.Length)], new Vector2(Random.Range(-1f, 1f), Random.Range(30f, 70f)), Quaternion.identity);
blot.transform.SetParent(paper.transform);
}
}
}
one solution is to test collider if obstacles is near the random position with Physics2D.OverlapCircleAll and using Layers:
of course obstacles have collider...
private void SpwanerPaper()
{
for (int i = 0; i < PlaningSpawn; i++)
{
if (rndType <= _dbPaperSpawn)
{
while (true)
{
var position = new Vector2(Random.Range(-1f, 1f), Random.Range(30f, 70f));
// i have choosen radius 1f, you could increase it if needed
Collider2D[] colliders = Physics2D.OverlapCircleAll(position, 1f, obstacleLayer);
if (colliders.Length == 0)
{
//so no obstacles present, spawn here
var blot = Instantiate(BlotPref[Random.Range(0, BlotPref.Length)],
position, Quaternion.identity);
blot.transform.SetParent(paper.transform);
break;// get out while loop
}
// so obstacles within 1m of the player loop again and give new random position
}
}
}
}
Following the situation you could use too Physics2D.CircleCastAll
If you dont know Layers, you have a tutorial youtube HERE
UPDATE
I managed to figure the answer out myself, what was happening was that my movement function was only registering the players original static position instead of the dynamic coordinates as the player moved around the screen. What I did was create a 'God' class to publicly store the players current X and Y coordinates, and then reference the 'god' class coordinates in my enemy's movement function.
Now, not only does the enemy detect when the player is within it's sights, it will follow the player changing directions accordingly, until it can't 'see' them anymore :D
If anyone wants to see the updated code just ask :)
I'm trying to make a program that contains player and enemy sprites, but I'm having a little trouble with the code for the 'Enemy'. Most of the coding problems on here deal with XNA, which I'm not using, so I was wondering if I could have a little help.
Basically, when the player moves within a certain distance, the movement function for the enemy should activate and it will move towards the players location as long as they're in the 'detection zone'. The enemy's sprite also has a walk animation for each direction, and it should flip through frames depending on whether it's currently moving or not.
The movement function is within a timer, so that it'll update with every tick. I have two separate functions for updating its location, one to physically change it's coordinates in the Form based on the data received from the movement function, and another to update the current frame from my sprite sheet.
The problem is that the enemy doesn't move whatsoever, if I get rid of it's detection and the code to follow the player, and instead just move it across the screen, it works perfectly fine. But unfortunately that's not what I'm trying to achieve.
The code works perfectly fine for my player sprite (albeit, it's controlled by the user and the keyboard keys), so I'm not sure what I'm doing wrong.
I believe the problems lies within the Movement function, but I'm not sure what that problem is exactly.
Here's my code for the relevant functions:
public void Movement() //This function is in a timer, and determines which direction the sprite will move and face
{
//The sprite rectangle is the position of the player sprite, and detection is the area where the enemy would 'see' the player if they entered it
sprite = new Rectangle(charX - 1, charY + 1, charWidth * 2 + 2, charHeight * 2 + 2);
Detection = new Rectangle(curX - 25, curY - 25, Enemy.Width * 6, Enemy.Height * 6);
if (Detection.IntersectsWith(sprite)) //Checks to see if the player is within range
{
//Moves the enemy based on the players position and changes direction accordingly
if (curX > charX)
{
curDirection = RIGHT;
dX = -1;
dY = 0;
numUpdates = 0;
curAnimation = MOVING;
}
else if (curX < charX)
{
curDirection = LEFT;
dX = 1;
dY = 0;
numUpdates = 0;
curAnimation = MOVING;
}
if (curY > charY)
{
curDirection = UP;
dY = -1;
dX = 0;
numUpdates = 0;
curAnimation = MOVING;
}
else if (curY < charY)
{
curDirection = DOWN;
dY = 1;
dX = 0;
numUpdates = 0;
curAnimation = MOVING;
}
}
//If not within range, don't move the sprite
else
{
dY = 0;
dX = 0;
curAnimation = FINISHED;
}
}
These are the updating functions that move the enemy and change the current frame
public void Follow() //Physcially moves the enemy across the form
{
int xMod = 0;
int yMod = 0;
if (dX != 0)
xMod = dX / Math.Abs(dX) * 2;
if (dY != 0)
yMod = dY / Math.Abs(dY) * 2;
//Moves the sprite across the x and y axis
curX += xMod;
dX += -xMod;
curY += yMod;
dY += -yMod;
}
public void UpdateFrame(int direction = DOWN)
{
numUpdates++;
switch (curAnimation)
{
//Stops the animation if the sprite stops moving
case FINISHED:
curFrame = 0;
break;
//Moves to the next frame when movement is found
case MOVING:
curFrame = (curFrame + 1) % 3;
Follow();
//check if done animation
if (dX == 0 && dY == 0) curAnimation = FINISHED;
break;
}
}
If you need more code just ask, any help is appreciated :)
I've been building an AI and currently I'm to the point where it mostly works as it should. I hit a few hitches at first, and had something that.. spazzed out. Now that is fixed, but there's a problem - this AI catches the ball 90% of the time and returns it, although somewhat slowly at times. I have yet to build the Attract mode of the game, but I can imagine... when that is in, the two AI will almost never score on eachother.
The game takes place on a 2D plane. The AI moves purely on X, locked into Z and Y while the ball moves on X and Y.
The playing field is set up like tennis, a 'net' in the center - 0,0,0, denotes the middle and the ball moves like a tennis ball does.
The AI (and player) uses two controls - 'Direction' to go either left or right, 1 for left, -1 for right, and a bool to trigger the ball return.
At the moment I just want it to 'miss' the ball every so often, not nearly perfectly every time. I'm programming in C#, with the game engine being Unity3D - here's my code for the AI engine thus far:
void AIHandle()
{
DetectBalls();
if (GameController.Instance.Balls.Count < 1) {
GetFlipperButton = false;
}
if (BallPosition) {
BallPosit = BallPosition.position;
BallX = BallPosit.x;
//BallVelPosit = BallPosition.gameObject.rigidbody.velocity;
//BallPosit.x += BallVelPosit.x;
//BallPosit.y += BallVelPosit.y;
//BallVelPosit.y -= Physics.gravity.y;
//BallHitPredictor = new Vector3 (BallPosit.x, 0, 0);
transformPoint = transform.InverseTransformPoint(BallPosit);
//////////////////
Vector3 Heading = BallPosit - transform.position;
if (BallX > 0) {
Debug.Log(Heading.sqrMagnitude);
// THe ball is to the left //
if (transformPoint.z < 0f)
{
Direction = 1;
}
// The ball is to the right //
if (transformPoint.z > 0f)
{
Direction = -1;
}
if (Heading.sqrMagnitude < 30.0f)
{
Direction = 0;
}
} else {
Retreat();
}
} else {
Retreat();
}
MovementDirection = Mathf.Lerp(MovementDirection, Direction, 2.0f);
}
private void Retreat()
{
float DistanceToCenter = Vector3.Distance(transform.position, PlayerStartPosition);
Vector3 CenterPointOrient = transform.InverseTransformPoint(PlayerStartPosition);
if (DistanceToCenter >= 1f) {
if (CenterPointOrient.z > 0) {
Direction = -1;
} else {
Direction = 1;
}
} else {
Direction = 0;
}
}
I tried creating a simple physics based "game" where you can spawn balls and they then get affected by different natural force, like gravity.
But I have a problem, when the ball reaches the floor, and it keeps getting affected by gravity. It kind of vibrates. Here's a quick example of how it looks.
And here is the code for collision detection and the gravity calculation.
public void CheckBounds(int maxHeight, int maxWidth)
{
if (this.position.Y + (radius + radius) > maxHeight)
this.velocity.Y = -Math.Abs(velocity.Y * 0.65f); // 0.65 is the "bouncyness"
}
Here is the main Update section
for (int i = 0; i < balls.Count; i++ )
{
Ball b = balls[i];
for (int k = 0; k < balls.Count; k++) // check for collision with other balls
{
if (balls[i] == balls[k])
continue;
if (balls[i].Colliding(balls[k]))
balls[i].Collide(balls[k]);
}
b.velocity.Y += gravitationalPull; // a gravity constant
b.CheckBounds();
b.position = Vector2.Add(b.position, b.velocity);
}
Does anyone know how to fix the vibration? I tried setting a minimum value of velocity that the gravity would be calculated (if velocity.y < some value then dont calculate), but then the ball stopped mid air at collisions and even at spawn.
I have NPC's in my game that follow a script where they move randomly around the game. I would like them to face the direction they are moving in though.
for (int i = 0; i < GameConstants.NumDaleks; i++)
{
if (dalekList[i].isActive)
{
Vector3 line = dalekList[i].direction;
float rotationDal = (float)(Math.Atan2(dalekList[i].position.Y, dalekList[i].position.X) / (2 * Math.PI));
Matrix dalekTransform = Matrix.CreateScale(GameConstants.DalekScalar) * Matrix.CreateRotationY(rotationDal) * Matrix.CreateTranslation(dalekList[i].position);
DrawModel(mdlDalek, dalekTransform, mdDalekTransforms);
}
}
I'm sure it must be something to do with rotationDal, I have tried changing the calculation and the characters do seem to rotate differently, just not in their current direction
Xna has a built in function that you might find handy here.
Matrix.CreateWorld(positionVector, DirectionVector, UpVector);
here's the doc: http://msdn.microsoft.com/en-us/library/bb975261(v=xnagamestudio.40).aspx
In your case:
for (int i = 0; i < GameConstants.NumDaleks; i++)
{
if (dalekList[i].isActive)
{
Matrix dalekTransform = Matrix.CreateScale(GameConstants.DalekScalar) * Matrix.CreateWorld(dalekList[i].position, dalekList[i].direction, Vector3.Up);
DrawModel(mdlDalek, dalekTransform, mdDalekTransforms);
}
}