This question already has answers here:
Rotate GameObject over time
(2 answers)
Closed 5 years ago.
I am using the following code to rotate my game objects over a given period of time:
IEnumerator RotateMe(Vector3 byAngles, float inTime)
{
Quaternion fromAngle = transform.rotation ;
Quaternion toAngle = Quaternion.Euler(transform.eulerAngles + byAngles) ;
for(float t = 0f ; t < 1f ; t += Time.deltaTime/inTime)
{
transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t) ;
yield return null ;
}
}
public void runCoroutine(Vector3 destination) {
StartCoroutine(RotateMe(destination, 0.5f));
}
then I call it in the following way:
runCoroutine(new Vector3(0,0,-90));
I realized from testing that my game objects are not rotating to the specified angles, but close them. Not really sure what is causing this.
I would have say that using Lerp method is better. For exact time related things, you'd have to introduce the lerp's rate.
transform.rotation = Quaternion.Lerp(fromAngle, toAngle, 1/value)
you can control the "value" to control the rate of rotation. I usually use this method to have a more controlled rotation.
NOTE: Make sure the lerping is done in a "per-frame" method call; update/fixed-update/late-update
Related
Currently doing a SoloProject for class and decided to study SpriteKit on my own. I decided to make a top-down zombie shooter and I have a lot of questions but so far these are the two main ones I can't seem to fix or find solution for.
Problem 1
Zombies slow down the closer they get to the target, If I increase the speed they just speed in from off the screen and still slowdown as they get closer (I've read somewhere putting that function in the update is bad but I still did it...)
I want to make it where they spawn with the speed of 3 and when the player moves closer or further away it stays at 3. (Currently using an analog stick code I found that was on Youtube to move my character around)
func zombieAttack() {
let location = player.position
for node in enemies {
let followPlayer = SKAction.move(to: player.position, duration: 3)
node.run(followPlayer)
//Aim
let dx = (location.x) - node.position.x
let dy = (location.y) - node.position.y
let angle = atan2(dy, dx)
node.zRotation = angle
//Seek
let velocityX = cos(angle) * 1
let velocityY = sin(angle) * 1
node.position.x += velocityX
node.position.y += velocityY
}
}
override func update(_ currentTime: TimeInterval) {
zombieAttack()
}
Problem 2
Also when multiple zombies get close to the players (function above) they start to spazz so I allowed them to overlap on top of each other to stop the spazzing.
I want to make it where they are more solid? if that is the right way to describe it. Basically I want them to huddle up around the player**.
If I add enemy to the collision it will spazz trying to get into the same position.
private func spawnZombie() {
let xPos = randomPosition(spriteSize: gameSpace.size)
let zombie = SKSpriteNode(imageNamed: "skeleton-idle_0")
zombie.position = CGPoint(x: -1 * xPos.x, y: -1 * xPos.y)
zombie.name = "Zombie\(zombieCounter)"
zombie.zPosition = NodesZPosition.enemy.rawValue
let presetTexture = SKTexture(imageNamed: "skeleton-idle_0.png")
zombie.physicsBody = SKPhysicsBody(texture: presetTexture, size: presetTexture.size())
zombie.physicsBody?.isDynamic = true
zombie.physicsBody?.affectedByGravity = false
zombie.physicsBody?.categoryBitMask = BodyType.enemy.rawValue
zombie.physicsBody?.contactTestBitMask = BodyType.bullet.rawValue
zombie.physicsBody?.collisionBitMask = BodyType.player.rawValue
zombie.zRotation = 1.5
zombie.setScale(0.2)
enemies.append(zombie)
zombieCounter += 1
run(SKAction.playSoundFileNamed("ZombieSpawn", waitForCompletion: false))
keepEnemiesSeperated() // ADDED FROM UPDATED EDIT*
addChild(zombie)
}
Let me know if I need to post more code or explain it better, I'm a five months in on learning Swift and have only a week and a half of SpriteKit experience and first time posting on StackOverFlow. Thanks all in advance!
EDIT: I am using a code I found from having a node follow at a constant speed but I don't think I'm doing it right since it is not working. I added the following code:
private func keepEnemiesSeparated() {
// Assign constrain
for enemy in enemies {
enemy.constraints = []
let distanceBetween = CGFloat(60)
let constraint = SKConstraint.distance(SKRange(lowerLimit: distanceBetween), to: enemy)
enemy.constraints!.append(constraint)
}
}
Problem 1, your zombie is moving based on time, not at a set speed. According to your code, he will always reach the player in 3 seconds. This means if he is 1 foot away, he takes 3 seconds. If he is 100 miles away, he takes 3 seconds. You need to use a dynamic duration if you are planning to use the moveTo SKAction based on the speed of the zombie. So if your zombie moves 10 points per second, you want to calculate the distance from zombie to player, and then divide by 10. Basically, your duration formula should be distance / speed
Problem 2, if you want the zombies to form a line, you are going to have to determine who the leading zombie is, and have each zombie follow the next leading zombie as opposed to all zombies following the player. Otherwise your other option is to not allow zombies to overlap, but again, you will still end up with more of a mosh pit then a line.
SCENARIO
I am creating an app where I have to show chemical bonding between atoms(which are game objects). I am using Leap motion hands for spawning and making atoms collide to form molecules. Now the bond between atoms are made using cylinder game objects.
Also when bond(cylinder) is spawned correctly it is joined to atoms' game objects using fixed joints.
All these things are working correctly and as intended.
PROBLEM:
As one atom can form bond with multiple atoms so I want to maintain a certain angle between each bonded atoms.(for eg. in chemistry CH4 molecule's atoms are separated by around 105 degrees).
So I want to achieve the same effect in my app too by separating each atom in molecule by certain angle.
What I currently have only create molecule properly but doesn't have anything to separate according to angle.
This is what I am doing currently.
private IEnumerator SetAtomPosition(Transform atomOne, Transform atomTwo, Transform cylinder)
{
cylinder.gameObject.GetComponent<Rigidbody>().isKinematic = true;
while (Vector3.Distance(atomOne.position, atomTwo.position) > atomDistance)
{
atomTwo.position = Vector3.MoveTowards(atomTwo.position, atomOne.position, Time.deltaTime * 0.1f);
yield return 0;
}
while (Vector3.Distance(atomOne.position, atomTwo.position) < atomDistance)
{
atomTwo.position = Vector3.MoveTowards(atomTwo.position, -atomTwo.forward * 1000f, Time.deltaTime * 0.1f);
yield return 0;
}
cylinder.transform.position = (atomTwo.position - atomOne.position) / 2.0f + atomOne.position;
cylinder.transform.rotation = Quaternion.FromToRotation(Vector3.up, atomTwo.position - atomOne.position);
#region JoinAtoms
cylinder.gameObject.AddComponent<FixedJoint>();
cylinder.gameObject.AddComponent<FixedJoint>();
var cylinderJoints = cylinder.GetComponents<FixedJoint>();
cylinderJoints[0].connectedBody = atomOne.GetComponent<Rigidbody>();
atomOne.GetComponent<Atom>().joint = cylinderJoints[0];
//cylinderJoints[0].breakForce = breakForce;
cylinderJoints[1].connectedBody = atomTwo.GetComponent<Rigidbody>();
atomTwo.GetComponent<Atom>().joint = cylinderJoints[1];
KinematicToggle(cylinder.gameObject);
cylinder.GetComponent<Rigidbody>().mass = 10f;
#endregion
yield return null;
}
And this is what it looks like currently
I want those 4 white spheres to be aligned around black sphere(Carbon atom).
What I want is something similar to this image.
I attempt implement a Three-view drawings shader for simple geometry and have test with this shader,simple as:
float doCos = dot(viewDirection, normalDirection);
float4 texColor;
//2. need board
bool isBackSide = doCos < 0;
if(isBackSide) {
//_Dotted is a 2d texture the board is black dot line
texColor = tex2D(_Dotted, i.tex.xy * _Dotted_ST.xy + _Dotted_ST.zw);
} else {
//_Dotted is a 2d texture the board is black entity line
texColor = tex2D(_Entity, i.tex.xy * _Entity_ST.xy + _Entity_ST.zw);
}
//ignore some color
if(texColor.x > 0.5f) {
discard;
}
return texColor;
There have a problem the dotted line will obvious then entity line when forward plane become steep.also, I add a rim line but its not point so I ignore it.
in order to clarify, I use two questions:
1. how to modify that shader solve dotted line problem?
2. Does have exist professional Three-view drawings shader?(not find yet)
In code below, I want to manage the amount of distance to travel when a left arrow key is pressed depending upon if it's half way down or not.
The object moves all the way to left on very first press instead of movement to be divided in 3 or 4 parts depending on the above mentioned condition, where am I doing it wrong?
var diff = Mathf.Abs(this.transform.position.x - r.renderer.bounds.min.x);
print("diff" + diff);
var lessdistancetotravel = diff/4;
var moredistancetotravel = diff/3;
if(this.transform.position.x > half)
{
print ("greater than half while moving left");
print("currentpos" + this.transform.position.x); //gives 0.6
print("moredistance " + moredistancetotravel);//gives 0.69
this.transform.position = new Vector3 (this.transform.position.x - moredistancetotravel,
this.transform.position.y,
this.transform.position.z);
print("updated" + (this.transform.position.x - moredistancetotravel)); //gives -0.78,How come?
}
Since you can't check how far down a key is pressed, as Jerdak mentioned in the comments. I would then just measure how long a key has been pressed. You can start counting how long the key has been down and stop counting once it is released. Then you can use that time to determine how far your object can travel.
How to count the time the key has been pressed:
float count = 0.0f;
void Update()
{
if(Input.GetKey("a"))
count += Time.deltaTime;
else if(Input.GetKeyUp("a"))
count = 0.0f;
}
Code resets count back to 0 once you release the key.
I am developing an application in which I want to add echo effect in recorded audio files using objective-c.
I am using DIRAC to add other effect e.g. man to women, slow, fast.
now I have to make Robot voice of recorded voice. for robot voice I need to add echo effect
Please help me to do this
Echo is pretty simple. You need a delay line, and little multiplication. Assuming one channel and audio already represented in floating point, a delay line would look something like this (in C-like pseudo-code):
int LENGTH = samplerate * seconds; //seconds is the desired length of the delay in seconds
float buffer[ LENGTH ];
int readIndex = 0, writeIndex = LENGTH - 1;
float delayLine.readNext( float x ) {
float ret = buffer[readIndex];
++readIndex;
if( readIndex >= LENGTH )
readIndex = 0;
return ret;
}
void delayLine.writeNext( float x ) {
buffer[ writeIndex ] = x;
++writeIndex;
if( writeIndex >= LENGTH )
writeIndex = 0;
}
Don't forget to initialize the buffer to all zeros.
So that's your delay line. Basic usage would be this:
float singleDelay( float x ) {
delayLine.writeNext(x);
return delayLine.readNext( x );
}
But you won't hear much difference: it'll just come out later. If you want to hear a single echo, you'll need something like this:
float singleEcho( float x, float g ) {
delayLine.writeNext(x);
return x + g * delayLine.readNext( x );
}
where g is some constant, usually between zero and one.
Now say you want a stream of echos: "HELLO... Hello... hello... h..." like that. You just need to do a bit more work:
float echo( float x, float g ) {
float ret = x + g * delayLine.readNext( x );
delayLine.writeNext( ret );
return ret;
}
Notice how the output of the whole thing is getting fed back into the delay line this time, rather than the input. In this case, it's very important that |g| < 1.
You may run into issues of denormals here. I can't recall if that's an issue on iOS, but I don't think so.