How to Instantiate a Rigidbody in Photon - unity3d

I'm trying to instantiate a knife in my multiplayer game (using Photon). I need it to be a rigidbody, as I change its velocity and need gravity. Here's what I currently have (only error is 0039, opposed to 0029)
Rigidbody knifeInstance;
knifeInstance = PhotonNetwork.Instantiate(Knife.name, SpawnerPos.position, SpawnerPos.rotation) as Rigidbody;
knifeInstance.velocity = new Vector3(-tempX * Speed * 4f, -tempY * Speed * 2.5f, -tempZ * Speed * 4f);
I of course have Photon.Pun added.
I've used "Instantiate( . . . ) as Rigidbody;" before, but now it doesn't work when I implement PhotonNetwork.Instantiate( . . . );

Related

ESP32 and MPU quaternion values are different - Unity3d shows different initial orentation of object

I am trying to build a 3D FPS game in unity. A friend of mine bought a (replica) gun and modified it to add an ESP32 and an MPU-9250 gyroscope/accelerometer in it to track and send the rotation of the gun (using quaternions) to unity. The problem is that each time I "power on" the gun and start the game the initial rotation of the weapon in the game is different. (I don't want to use euler angles because of the gimbal lock problem.) Any ideas where the problem might be and how to fix it?
I am currently using the MPU-9250 DMP Arduino Library as in here.
I have started thinking that the problem lies on the fact that each time I turn on the power of the gun, the gyroscope axes are reinitialized. According to another library - Calibration - accel/gyro/mag offsets are NOT stored to register if the MPU has powered off. You need to set all offsets at every bootup by yourself (or calibrate at every bootup). I do not want to do that every time the ESP32 is restarted. If only I could use a fixed coordinate system no matter what the position of the gun is, when the ESP32 reboots.
Here is the code I have written so far:
#include "src\lib\SparkFunMPU9250-DMP.h"
#include <WiFi.h>
#include <WiFiUdp.h>
// -------------------------------------------------------------------------------------------
// Enter: WEAPON_* OR Handgun_*
const String gun = "Handgun_4";
char * udpAddress;
int udpPort;
int Trigger;
int Mag;
int Shutter;
// -------------------------------------------------------------------------------------------
// --- Trigger ---
//const int Trigger = 4;
int button_state_trigger = 0;
int button_state_mag = 0;
int button_state_shutter = 0;
// --- MPU9250 ---
MPU9250_DMP imu;
// --- WiFi ---
WiFiUDP udp;
// WIFI credentials
const char * networkName = "...";
const char * networkPswd = "...";
// IP address to send UDP data to:
// either use the ip address of the server or
// a network broadcast address
//const char * udpAddress = ...;
// UDP port
//const int udpPort = ...;
// payload to sent
String payload = "";
//Connection state?
boolean connected = false;
// Timers
unsigned long timer1, timer2;
// -------------------------------------------------------------------------------------------
void setup() {
GunSelect(gun);
// Initialize Serial Com
Serial.begin(115200);
// Initialize Trigger
pinMode(Trigger, INPUT);
pinMode(Mag, INPUT);
pinMode(Shutter, INPUT);
// Initialize MPU9250
while (imu.begin() != INV_SUCCESS) {
Serial.println("Unable to communicate with MPU-9250");
delay(2000);
}
imu.setSensors(INV_XYZ_GYRO | INV_XYZ_ACCEL | INV_XYZ_COMPASS); // Enable all sensors
imu.setGyroFSR(2000); // Set Gyro dps, options are +/- 250, 500, 1000, or 2000 dps
imu.setAccelFSR(16); // Set Accel g, options are +/- 2, 4, 8, or 16 g
imu.setSampleRate(100); // Set sample rate of Accel/Gyro, range between 4Hz-1kHz
imu.setLPF(5); // Set LPF corner frequency of Accel/Gyro, acceptable cvalues are 188, 98, 42, 20, 10, 5 (Hz)
imu.setCompassSampleRate(100); // Set Mag rate, range between: 1-100Hz
imu.dmpBegin(DMP_FEATURE_6X_LP_QUAT | // 6-axis (accel/gyro) quaternion calculation
DMP_FEATURE_GYRO_CAL , // Gyroscope calibration (0's out after 8 seconds of no motion)
200);
delay(10000);
// Initialize WiFi
connectToWiFi(networkName, networkPswd);
}
// -------------------------------------------------------------------------------------------
void loop() {
// Timer Start
// timer1 = micros();
if ( imu.fifoAvailable() ) {
if ( imu.dmpUpdateFifo() == INV_SUCCESS ) {
// Switches Read
button_state_trigger = buttonState(Trigger);
if (gun == "WEAPON_1" || gun == "WEAPON_2" || gun == "WEAPON_3" || gun == "WEAPON_4" || gun == "WEAPON_5" || gun == "WEAPON_Test") {
button_state_mag = buttonState(Mag);
button_state_shutter = buttonState(Shutter);
}
double x = imu.calcQuat(imu.qx);
double y = imu.calcQuat(imu.qy);
double z = imu.calcQuat(imu.qz);
double w = imu.calcQuat(imu.qw);
Serial.println();
Serial.println(button_state_trigger);
Serial.println(button_state_mag);
Serial.println(button_state_shutter);
Serial.println("x: " + String(x));
Serial.println("y: " + String(y));
Serial.println("z: " + String(z));
Serial.println("w: " + String(w));
Serial.println();
//*/
// Send data via WiFi
payload = "ACC|" + String(x,4) + "|" + String(y,4) + "|" + String(z,4) + "|" + String(w,4) + "|" + String(button_state_trigger) + "|" + String(button_state_mag) + "|" + String(button_state_shutter);
sendData(payload);
}
}
// Timer End
// timer2 = micros();
// Serial.println(timer2 - timer1);
}
In Unity I receive the data and parse it as 4 floats. Then I set the gun's rotation in the game as (y,w,-x,z) because the coordinate system of the gun is different from the one that Unity uses. So the code is like:
// Receiving data...
float x = float.Parse(data[1]);
float y = float.Parse(data[2]);
float z = float.Parse(data[3]);
float w = float.Parse(data[4]);
gun.rotation = new Quaternion(y,w,-x,z);
----------------Edit--------------------
I read about Madgwick filter (alternatively Kalman filter and Mahony filter) which is said to be able to produce a quaternion-based estimate of absolute device orientation (based on the earth's reference system ie. North etc.) If I understood correctly . But I am not really sure if that solves my problem.

SKNodes follow in a consistent speed and stop them from spazzing?

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.

How to set specific angle between 2 game objects in unity

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.

Game object not rotating to correct specified angle [duplicate]

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

How to write a Three-view drawings shader(in Unity3d)?

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)