I'd like to assign data to a object - c#

I receive the data which are X, Y, Z position and X, Y, Z rotation by Using UDP real time(60hz)
I used the code by la1n.(http://forum.unity3d.com/threads/simple-udp-implementation-send-read-via-mono-c.15900/)
I write the code myself by using la1n's code. But I have some troubles.
First, I think I complete string split and parse by using array.
Is there any problem in split and parse?
I have a problem about matching data(x,y,z pos and x,y,z rot) to Object(box).
I attached my code(which are c# and lua script)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
public class UDPReceive : MonoBehaviour
{
// receiving Thread
Thread receiveThread;
// udpclient object
UdpClient client;
// port
public int port = 8051; // define > init
// infos
public string lastReceivedUDPPacket = "";
// start from shell
private static void Main()
{
UDPReceive receiveObj = new UDPReceive();
receiveObj.init();
string text = "";
do
{
text = Console.ReadLine();
}
while (!text.Equals("exit"));
}
// start from unity3d
public void Start()
{
init();
}
void SetTransform(float XPos, float YPos, float ZPos)
{
transform.position = new Vector3(XPos, YPos, ZPos);
}
void SetRotation(float XRot, float YRot, float ZRot)
{
transform.eulerAngles = new Vector3(XRot, YRot, ZRot);
}
void Update()
{
SetTransform();
SetRotation();
}
// OnGUI
void OnGUI()
{
Rect rectObj = new Rect(40, 10, 200, 400);
GUIStyle style = new GUIStyle();
style.alignment = TextAnchor.UpperLeft;
GUI.Box(rectObj, "\nLast Packet: \n" + lastReceivedUDPPacket, style);
}
// init
private void init()
{
// Endpunkt definieren, von dem die Nachrichten gesendet werden.
print("UDPSend.init()");
// define port
port = 8051;
// status
print("Sending to 127.0.0.1 : " + port);
print("Test-Sending to this Port: nc -u 127.0.0.1 " + port + "");
// ----------------------------
// Abhören
// ----------------------------
// Lokalen Endpunkt definieren (wo Nachrichten empfangen werden).
// Einen neuen Thread für den Empfang eingehender Nachrichten erstellen.
receiveThread = new Thread(
new ThreadStart(ReceiveData));
receiveThread.IsBackground = true;
receiveThread.Start();
}
// Unity Application Quit Function
void OnApplicationQuit()
{
stopThread();
}
// Stop reading UDP messages
private void stopThread()
{
if (receiveThread.IsAlive)
{
receiveThread.Abort();
}
client.Close();
}
// receive thread
private void ReceiveData()
{
client = new UdpClient(port);
while (true)
{
try
{
// Bytes empfangen.
IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
byte[] data = client.Receive(ref anyIP);
// Bytes mit der UTF8-Kodierung in das Textformat kodieren.
string text = Encoding.UTF8.GetString(data);
// Data Received from simulation
print("Received Data >> " + text);
// latest UDPpacket
lastReceivedUDPPacket = text;
}
catch (Exception err)
{
print(err.ToString());
}
}
}
private void parseDataToCrane ( string text )
{
try
{
float[] floatData = Array.ConvertAll(text.Split(';'), float.Parse);
float XPos = floatData[0];
float YPos = floatData[1];
float ZPos = floatData[2];
float XRot = floatData[3];
float YRot = floatData[4];
float ZRot = floatData[5];
}
catch (Exception err)
{
print(err.ToString());
}
}
}
This code is simulation code and It is written by Lua Script.
socket = require("socket")
print(socket._VERSION)
function dataListener:post( t )
local XPos = ship.rb:getPosition():x()
local YPos = ship.rb:getPosition():y()
local ZPos = ship.rb:getPosition():z()
local XXPos = math.floor( XPos * 1000 + 0.5 ) / 1000
local YYPos = math.floor( YPos * 1000 + 0.5 ) / 1000
local ZZPos = math.floor( ZPos * 1000 + 0.5 ) / 1000
local XRot = ship.rb:getRotation():x()
local YRot = ship.rb:getRotation():y()
local ZRot = ship.rb:getRotation():z()
local XXRot = math.floor( XPos * 1000 + 0.5 ) / 1000
local YYRot = math.floor( YPos * 1000 + 0.5 ) / 1000
local ZZRot = math.floor( ZPos * 1000 + 0.5 ) / 1000
udp=socket.udp();
udp:setpeername("127.0.0.1",8051)
udp:send(string.format("%f; %f; %f; %f; %f; %f", XXPos, YYPos, ZZPos, XXRot, YYRot, ZZRot));
end
I have worked for 3 hours. But Whenever I debug, Errors occur and It doesn't work...

Related

Unity: Live Video Streaming ARCore Camera Texture

I'm trying to use TCP sockets to stream the texture from the ARCore camera on one device to the background image on another device. I've found some great resources that have got me close. This question helped me a lot: Unity: Live Video Streaming
The only difference is that this example uses a WebcamTexture, which I've got working without any lag and smoothly.
However, obtaining the camera texture from ARCore is a bit of a different process. I think I'm doing this correctly but maybe I'm missing something. When I run this with the ARCore camera texture and my minor changes, the server lags significantly.
Below is my code. I made no changes to the client side code so I know it has to do with my server side changes.
SERVER:
public class MySocketServer : MonoBehaviour
{
WebCamTexture webCam;
public RawImage myImage;
public bool enableLog = false;
Texture2D currentTexture;
private TcpListener listner;
private const int port = 8010;
private bool stop = false;
private List<TcpClient> clients = new List<TcpClient>();
//This must be the-same with SEND_COUNT on the client
const int SEND_RECEIVE_COUNT = 15;
private void Start()
{
Application.runInBackground = true;
//Start WebCam coroutine
StartCoroutine(initAndWaitForWebCamTexture());
}
//Converts the data size to byte array and put result to the fullBytes array
void byteLengthToFrameByteArray(int byteLength, byte[] fullBytes)
{
//Clear old data
Array.Clear(fullBytes, 0, fullBytes.Length);
//Convert int to bytes
byte[] bytesToSendCount = BitConverter.GetBytes(byteLength);
//Copy result to fullBytes
bytesToSendCount.CopyTo(fullBytes, 0);
}
//Converts the byte array to the data size and returns the result
int frameByteArrayToByteLength(byte[] frameBytesLength)
{
int byteLength = BitConverter.ToInt32(frameBytesLength, 0);
return byteLength;
}
IEnumerator initAndWaitForWebCamTexture()
{
// Open the Camera on the desired device, in my case IPAD pro
//webCam = new WebCamTexture();
// Get all devices , front and back camera
//webCam.deviceName = WebCamTexture.devices[WebCamTexture.devices.Length - 1].name;
// request the lowest width and heigh possible
//webCam.requestedHeight = 10;
//webCam.requestedWidth = 10;
//myImage.texture = webCam;
//webCam.Play();
//currentTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24,false);
//currentTexture = new Texture2D(webCam.width, webCam.height);
// Connect to the server
listner = new TcpListener(IPAddress.Any, port);
listner.Start();
while (Screen.width < 100)
{
yield return null;
}
//Start sending coroutine
StartCoroutine(senderCOR());
}
WaitForEndOfFrame endOfFrame = new WaitForEndOfFrame();
IEnumerator senderCOR()
{
bool isConnected = false;
TcpClient client = null;
NetworkStream stream = null;
// Wait for client to connect in another Thread
Loom.RunAsync(() =>
{
while (!stop)
{
// Wait for client connection
client = listner.AcceptTcpClient();
// We are connected
clients.Add(client);
isConnected = true;
stream = client.GetStream();
}
});
//Wait until client has connected
while (!isConnected)
{
yield return null;
}
LOG("Connected!");
bool readyToGetFrame = true;
byte[] frameBytesLength = new byte[SEND_RECEIVE_COUNT];
while (!stop)
{
//Wait for End of frame
yield return endOfFrame;
//currentTexture.ReadPixels(new Rect(0,0,Screen.width,Screen.height), 0, 0);
//currentTexture.Apply();
//NEW CODE TO TRY
using (var image = Frame.CameraImage.AcquireCameraImageBytes()) {
if(!image.IsAvailable)
{
yield return null;
}
_OnImageAvailable(image.Width, image.Height, image.Y, image.Width * image.Height);
}
//currentTexture.SetPixels(webCam.GetPixels());
byte[] pngBytes = currentTexture.EncodeToPNG();
//Fill total byte length to send. Result is stored in frameBytesLength
byteLengthToFrameByteArray(pngBytes.Length, frameBytesLength);
//Set readyToGetFrame false
readyToGetFrame = false;
Loom.RunAsync(() =>
{
//Send total byte count first
stream.Write(frameBytesLength, 0, frameBytesLength.Length);
LOG("Sent Image byte Length: " + frameBytesLength.Length);
//Send the image bytes
stream.Write(pngBytes, 0, pngBytes.Length);
LOG("Sending Image byte array data : " + pngBytes.Length);
//Sent. Set readyToGetFrame true
readyToGetFrame = true;
});
//Wait until we are ready to get new frame(Until we are done sending data)
while (!readyToGetFrame)
{
LOG("Waiting To get new frame");
yield return null;
}
}
}
void LOG(string messsage)
{
if (enableLog)
Debug.Log(messsage);
}
private void Update()
{
myImage.texture = webCam;
}
// stop everything
private void OnApplicationQuit()
{
if (webCam != null && webCam.isPlaying)
{
webCam.Stop();
stop = true;
}
if (listner != null)
{
listner.Stop();
}
foreach (TcpClient c in clients)
c.Close();
}
private void _OnImageAvailable(int width, int height, IntPtr pixelBuffer, int bufferSize){
currentTexture = new Texture2D(width, height, TextureFormat.RGBA32, false, false);
byte[] bufferYUV = new byte[width * height * 3 / 2];
bufferSize = width * height * 3 / 2;
System.Runtime.InteropServices.Marshal.Copy(pixelBuffer, bufferYUV, 0, bufferSize);
Color color = new Color();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
float Yvalue = bufferYUV[y * width + x];
float Uvalue = bufferYUV[(y / 2) * (width / 2) + x / 2 + (width * height)];
float Vvalue = bufferYUV[(y / 2) * (width / 2) + x / 2 + (width * height) + (width * height) / 4];
color.r = Yvalue + (float)(1.37705 * (Vvalue - 128.0f));
color.g = Yvalue - (float)(0.698001 * (Vvalue - 128.0f)) - (float)(0.337633 * (Uvalue - 128.0f));
color.b = Yvalue + (float)(1.732446 * (Uvalue - 128.0f));
color.r /= 255.0f;
color.g /= 255.0f;
color.b /= 255.0f;
if (color.r < 0.0f)
color.r = 0.0f;
if (color.g < 0.0f)
color.g = 0.0f;
if (color.b < 0.0f)
color.b = 0.0f;
if (color.r > 1.0f)
color.r = 1.0f;
if (color.g > 1.0f)
color.g = 1.0f;
if (color.b > 1.0f)
color.b = 1.0f;
color.a = 1.0f;
currentTexture.SetPixel(width - 1 - x, y, color);
}
}
currentTexture.Apply();
//this.GetComponent<RawImage>().texture = m_TextureRender;
}
}
CLIENT
public class MySocketsClient : MonoBehaviour
{
public RawImage image;
public bool enableLog = false;
const int port = 8010;
//public string IP = "xxx.xxx.x.xx";
public string IP = "xxx.xxx.x.x";
TcpClient client;
Texture2D tex;
private bool stop = false;
//This must be the-same with SEND_COUNT on the server
const int SEND_RECEIVE_COUNT = 15;
// Use this for initialization
void Start()
{
Application.runInBackground = true;
tex = new Texture2D(0, 0);
client = new TcpClient();
//Connect to server from another Thread
Loom.RunAsync(() =>
{
LOGWARNING("Connecting to server...");
// if on desktop
//client.Connect(IPAddress.Loopback, port);
// if using the IPAD
client.Connect(IPAddress.Parse(IP), port);
LOGWARNING("Connected!");
imageReceiver();
});
}
void imageReceiver()
{
Debug.Log("Here");
//While loop in another Thread is fine so we don't block main Unity Thread
Loom.RunAsync(() =>
{
while (!stop)
{
//Read Image Count
int imageSize = readImageByteSize(SEND_RECEIVE_COUNT);
LOGWARNING("Received Image byte Length: " + imageSize);
//Read Image Bytes and Display it
readFrameByteArray(imageSize);
}
});
}
//Converts the data size to byte array and put result to the fullBytes array
void byteLengthToFrameByteArray(int byteLength, byte[] fullBytes)
{
//Clear old data
Array.Clear(fullBytes, 0, fullBytes.Length);
//Convert int to bytes
byte[] bytesToSendCount = BitConverter.GetBytes(byteLength);
//Copy result to fullBytes
bytesToSendCount.CopyTo(fullBytes, 0);
}
//Converts the byte array to the data size and returns the result
int frameByteArrayToByteLength(byte[] frameBytesLength)
{
int byteLength = BitConverter.ToInt32(frameBytesLength, 0);
return byteLength;
}
/////////////////////////////////////////////////////Read Image SIZE from Server///////////////////////////////////////////////////
private int readImageByteSize(int size)
{
bool disconnected = false;
NetworkStream serverStream = client.GetStream();
byte[] imageBytesCount = new byte[size];
var total = 0;
do
{
var read = serverStream.Read(imageBytesCount, total, size - total);
//Debug.LogFormat("Client recieved {0} bytes", total);
if (read == 0)
{
disconnected = true;
break;
}
total += read;
} while (total != size);
int byteLength;
if (disconnected)
{
byteLength = -1;
}
else
{
byteLength = frameByteArrayToByteLength(imageBytesCount);
}
return byteLength;
}
/////////////////////////////////////////////////////Read Image Data Byte Array from Server///////////////////////////////////////////////////
private void readFrameByteArray(int size)
{
bool disconnected = false;
NetworkStream serverStream = client.GetStream();
byte[] imageBytes = new byte[size];
var total = 0;
do
{
var read = serverStream.Read(imageBytes, total, size - total);
//Debug.LogFormat("Client recieved {0} bytes", total);
if (read == 0)
{
disconnected = true;
break;
}
total += read;
} while (total != size);
bool readyToReadAgain = false;
//Display Image
if (!disconnected)
{
//Display Image on the main Thread
Loom.QueueOnMainThread(() =>
{
displayReceivedImage(imageBytes);
readyToReadAgain = true;
});
}
//Wait until old Image is displayed
while (!readyToReadAgain)
{
System.Threading.Thread.Sleep(1);
}
}
void displayReceivedImage(byte[] receivedImageBytes)
{
tex.LoadImage(receivedImageBytes);
image.texture = tex;
}
// Update is called once per frame
void Update()
{
}
void LOG(string messsage)
{
if (enableLog)
Debug.Log(messsage);
}
void LOGWARNING(string messsage)
{
if (enableLog)
Debug.LogWarning(messsage);
}
void OnApplicationQuit()
{
LOGWARNING("OnApplicationQuit");
stop = true;
if (client != null)
{
client.Close();
}
}
}
Would appreciate any help or thoughts on what might be causing the severe lag. Thanks!

Microphone input's maximum float number is 1. How to make it bigger and change it from 1? Unity C#

I have a code that takes a microphone input(when pressing "T)" and returns it as a float number (one final float number). However, when I yell or blow into microphone the maximum float it prints is 1 and no matter how I yell or say quietly after it printed 1, it keeps printing 1 only. How to change it to a bigger number. Let's say if I yell it would return a bigger number than if I just say quietly.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class MicInputs : MonoBehaviour
{
public enum micActivation
{
HoldToSpeak,
}
public micActivation micControl;
private float sample_max = 0.0f;
public static float MicLoudFloat;
public List<float> recorded_values = new List<float>();
private string theMicroDevice;
AudioClip recordOfClips;
//microphone initialization
void MicroInitialization()
{
if (theMicroDevice == null) theMicroDevice = Microphone.devices[0];
recordOfClips = Microphone.Start(theMicroDevice, true, 999, 44100);
}
void StopMicrophone()
{
Microphone.End(theMicroDevice);
Maximum_Level(); // Collect the final sample
MicLoudFloat = sample_max;
print(MicLoudFloat);
}
void Awake()
{
recordOfClips = AudioClip.Create("nameOfClip", 128, 2, 1000, true);
}
//AudioClip clip = myRecordedOrOwnClip;
//reate(string name, int lengthSamples, int channels, int frequency,
bool stream,
//_sampleWindow = clip.samples;
//AudioClip _clipRecord = new AudioClip();
//AudioClip _clipRecord = AudioClip.Create("nameOfClip", 128, 2, 1,
true);
int samplesWindows = 128;
//=========THIS IS THE START OF THE METHOD========
// get data from microphone into audioclip
float Maximum_Level()
{
float[] waveData = new float[samplesWindows];
int micPosition = Microphone.GetPosition(null) - (samplesWindows
+1); // null means the first microphone
if (micPosition < 0) return 0;
recordOfClips.GetData(waveData, micPosition);
// Getting a peak on the last 128 samples
for (int i = 0; i < samplesWindows; i++)
{
float wavePeak = waveData[i] * waveData[i];
if (wavePeak > sample_max)
{
sample_max = wavePeak;
}
}
return sample_max;
//float maximum_level = 0;
//float[] waveData = new float[samplesWindows];
//int micPosition = Microphone.GetPosition(null) - (samplesWindows
+ 1); // null means the first microphone
//if (micPosition < 0) return 0;
//recordOfClips.GetData(waveData, micPosition);
//// Getting a peak on the last 128 samples
//for (int i = 0; i < samplesWindows; i++)
//{
// float wavePeak = waveData[i] * waveData[i];
// if (maximum_level < wavePeak)
// {
// maximum_level = wavePeak;
// recorded_values.Add(maximum_level);
// }
//}
//float max = recorded_values.Max();
////print(max);
//return max;
//print(maximum_level);
//return maximum_level;
}
//=========THIS IS THE END OF THE METHOD========
void Update()
{
if (micControl == micActivation.HoldToSpeak)
{
//if (Microphone.IsRecording(theMicroDevice) &&
Input.GetKey(KeyCode.T) == false)
//StopMicrophone();
//
if (Input.GetKeyDown(KeyCode.T)){ //Push to talk
MicroInitialization();
}
//
if (Input.GetKeyUp(KeyCode.T)){
StopMicrophone();
}
}
Maximum_Level();
// levelMax equals to the highest normalized value power 2, a small
number because < 1
// pass the value to a static var so we can access it from anywhere
//print(MicLoudFloat);
}
//bool isItInitialized;
//// start mic when scene starts
//void OnEnable()
//{
// MicroInitialization();
// isItInitialized = true;
//}
////stop mic when loading a new level or quit application
//void OnDisable()
//{
// StopMicrophone();
//}
//void OnDestroy()
//{
// StopMicrophone();
//}
// detects if the mic gets started & stopped when application gets
focused
//void OnApplicationFocus(bool focus)
//{
// if (focus)
// {
// //Debug.Log("Focus");
// if (!isItInitialized)
// {
// //Debug.Log("Init Mic");
// MicroInitialization();
// isItInitialized = true;
// }
// }
// if (!focus)
// {
// //Debug.Log("Pause");
// StopMicrophone();
// //Debug.Log("Stop Mic");
// isItInitialized = false;
// }
//}
}
The sensor returns only a 0 or a 1, it's not 0->inf, if you want to something else, like checking how load is the voice from 0 to 100, you could record it and check the audio file highest bump and return that.

Unity double click(keyboard) with Time.deltaTime [duplicate]

This question already has answers here:
Unity Input detected multiple times in a press
(2 answers)
Closed 5 years ago.
I'm Unity starter and wanna make game that
ROTATE with ↖(7), ↗(9) (need double pressing also)
MOVE with ↑↓←→ on numpad 8,5,4,6 (double and also need something like ←↑→+Q)
.
I need to detect double input like ↗↗ at exact time and count
but sometimes it detected twice even if I double press only once...
this is part of my C# script. (full src is included under)
void Update () {
//get input
is_r = Input.GetButton ("Keypad9");
is_l = Input.GetButton ("Keypad7");
is_rr= false;
is_ll= false;
if (is_r) {
float gap = Time.time - time_r;
if (Time.deltaTime + 0.05 < gap && gap < time_maxgap) {
//seems like if Time.deltaTime change more than 0.05sec it works wrong
is_rr = true;
print ("deltatime = " + Time.deltaTime + "gap = " + gap);
}
time_r = Time.time;
}
// and more codes below
I think it's because of Time.deltaTime is diffrent for all frames.
And similer problem happened in movement(↑↓←→) command input too. (I'd like to start dash with ↑↑) It sometimes detected twice even if I make source in diffrent style.
If you know HOW TO FIX this problem OR BETTER SOLUTION to avoid problem, please help me. (and i'm not good at english)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraInputFilter : MonoBehaviour {
float time_maxgap = 0.3f;
float time_r = 0f,
time_l = 0f;
bool is_r = false,
is_l = false,
is_rr= false,
is_ll= false;
// Use this for initialization
void Start () {}
// Update is called once per frame
void Update () {
//get input
is_r = Input.GetButton ("Keypad9");
is_l = Input.GetButton ("Keypad7");
is_rr= false;
is_ll= false;
if (is_r) {
float gap = Time.time - time_r;
if (Time.deltaTime + 0.03 < gap && gap < time_maxgap) {
is_rr = true;
print ("deltatime = " + Time.deltaTime + "gap = " + gap);
}
time_r = Time.time;
}
if (is_l) {
float gap = Time.time - time_l;
if (Time.deltaTime + 0.01 < gap && gap < time_maxgap) {
is_ll = true;
}
time_l = Time.time;
}
//send out result
if (is_rr) {
print ("rr");
} else if (is_ll) {
print ("ll");
} else if (is_r && ! is_l){
print ("r");
} else if (is_l && ! is_r){
print ("l");
}
}
}
this code is made in difrent style.
Use history and not use deltaTime as minimum timegap
but similiar problem happens
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CommandFilter : MonoBehaviour {
public GameObject obj;
const float time_maxgap = 0.3f;
//Key Code
//todo : extract these codes into header file
const int up = 1;
const int down = 2;
const int right = 3;
const int left = 4;
const int sk1 = 5;
const int sk2 = 6;
const int sk3 = 7;
const int signal= 8; //not a key input. used as counter & new_state signal
//Keystate Code
const int idle = 0;
const int on = +1;
const int on_new = on * signal;
const int off = -1;
const int off_new = off * signal;
//input for now, last (only 2 needed), input[0] not used.
int[] input_new = new int[signal];
int[] input_last= new int[signal];
float time_deadline = 0f;
//history of input summery(only 1 KEYSTATE CODE(int) saved)
LinkedList<int> history = new LinkedList<int>();
//Keystate summery
//Usage : Keycode * Keystatecode
//ex) history.Enque(up * on_new)
//----------------------------------
void Start () {
HistoryInit ();
input_last [up] = off; //these initializatiolns needs only once at start
input_last [down] = off; //to make Compairing Last & New State works
input_last [right] = off;
input_last [left] = off;
input_last [sk1] = off;
input_last [sk2] = off;
input_last [sk3] = off;
}
void Update(){
//save currunt key state
input_new [up] = Input.GetButton ("Keypad8")? on:off;
input_new [down] = Input.GetButton ("Keypad5")? on:off;
input_new [right] = Input.GetButton ("Keypad6")? on:off;
input_new [left] = Input.GetButton ("Keypad4")? on:off; //unexpected error : can't get 4 dirs at once. but not important now
input_new [sk1] = Input.GetButton ("Skill1") ? on:off;
input_new [sk2] = Input.GetButton ("Skill2") ? on:off;
input_new [sk3] = Input.GetButton ("Skill3") ? on:off;
//print("input_current : " + input_new[up] + " " + input_new[down] + " " + input_new[right] + " " + input_new[left]);
//mark new changes by compairing with last input (on -> on_new, off -> off_new) and save currunt input
bool no_change = true;
for(int i = up; i < signal; i++){
if (input_last [i] * input_new [i] < 0) { //if button state changed (0 < on * on_new, same for off too)
no_change = false; //report change
input_last [i] = input_new [i] * signal; //save change
HistoryAdd(input_last[i] * i); //save change
//print("new input : " + input_last[i]);
}
}
if (no_change && history.First != null && history.First.Value != idle) {
HistoryAdd (idle);
} else if ((no_change && time_deadline < Time.time)) { //if input not change for more than command time gap(ex 0.3 sec)
HistoryInit (); //remove all history
}
string str = "";
foreach (int i in history) {
str += (i + " ");
}
int pattern = PatternSearch();
if (pattern != 0) {
print ("pattern " + pattern /*+ " found\tcurrent history : " + str*/);
} else {
//print ("history : " + str);
}
}
void HistoryInit(){
time_deadline = Time.time + time_maxgap;
history.Clear ();
print ("HistoryInit");
}
void HistoryAdd(int summery_code){
time_deadline = Time.time + time_maxgap;
if (history.First != null && history.First.Value == idle) {
history.RemoveFirst ();
}
history.AddFirst(summery_code);
}
int PatternSearch(){//hard corded patterns now. need to be reformed
//Search pattern : evade front
int[][] patterns = new int[][]{
//todo2 : extract pattern list into other txt file
//todo1 : make converter (string input -> int use)
//ex) "34 checkoff U+ U- U+ U-" -> evade up, return 34
//ex) "44 dontcare U+ U+" -> dash up, return 44, dont care keyoff
new int[] {}, //0 not used
new int[] { 0, on_new * left ,on_new * up ,on_new * right,on_new * sk2 }, // multishot (0 : not checkdown)
new int[] { 1, on_new * up ,off_new * up ,on_new * up ,off_new * up }, // evade (1:checkdown)
new int[] { 1, on_new * down ,off_new * down ,on_new * down ,off_new * down }, // evade (1:checkdown)
new int[] { 1, on_new * right ,off_new * right,on_new * right,off_new * right}, // evade (1:checkdown)
new int[] { 1, on_new * left ,off_new * left ,on_new * left ,off_new * left }, // evade (1:checkdown)
new int[] { 0, on_new * up ,on_new * up}, // start dash (0 : not checkdown)
new int[] { 0, on_new * down ,on_new * down}, // start dash (0 : not checkdown)
new int[] { 0, on_new * right ,on_new * right}, // start dash (0 : not checkdown)
new int[] { 0, on_new * left ,on_new * left}, // start dash (0 : not checkdown)
new int[] { 1, on_new * sk2 }, // 평타
};
for(int i = 1; i <patterns.Length; i++){
if (PatternMatch (patterns [i])) { return i;}
}
return 0;
}
bool PatternMatch(int [] pattern){
bool checkdown = (pattern [0] == 1);
LinkedListNode<int> it;
int i = 0;
//string str = "";
for (i = pattern.Length - 1, it = history.First; it != null; i--, it = it.Next) {
while(!checkdown && it.Value < 0){
it = it.Next;
if (it == null) {break;}
}
if (it == null) {break;}
//str += pattern [i];
if (pattern[i] != it.Value){
break;
}
if (i == 1) { //pattern[0] not used. it's just option
return true;//pattern fully match
}
}
return false; //pattern not match
}
}
Not sure, but try Input.GetButtonDown instead of Input.GetButton.
Input.GetButton will be true while you hold a key pressed, so it can be cause of your "double detection".

Xamarin Urho IOS how to set up an application?

I am following this example but it is not that useful:
https://github.com/xamarin/urho-samples/tree/master/FeatureSamples/Core/29_SoundSynthesis
anyhow I am getting an run time error that says: The application is not configured yet.
but I made an application object .
the error happen a node = new Node();
what am I missing
this is my class:
using System;
using Urho.Audio;
using Urho;
using Urho.Resources;
using Urho.Gui;
using System.Diagnostics;
using System.Globalization;
namespace Brain_Entrainment
{
public class IsochronicTones : Urho.Application
{
/// Scene node for the sound component.
Node node;
/// Sound stream that we update.
BufferedSoundStream soundStream;
public double Frequency { get; set; }
public double Beat { get; set; }
public double Amplitude { get; set; }
public float Bufferlength { get; set; }
const int numBuffers = 3;
public IsochronicTones(ApplicationOptions AppOption) : base(AppOption)
{
Amplitude = 1;
Frequency = 100;
Beat = 0;
Bufferlength = Int32.MaxValue;
}
public void play()
{
Start();
}
protected override void OnUpdate(float timeStep)
{
UpdateSound();
base.OnUpdate(timeStep);
}
protected override void Start()
{
base.Start();
CreateSound();
}
void CreateSound()
{
// Sound source needs a node so that it is considered enabled
node = new Node();
SoundSource source = node.CreateComponent();
soundStream = new BufferedSoundStream();
// Set format: 44100 Hz, sixteen bit, mono
soundStream.SetFormat(44100, true, false);
// Start playback. We don't have data in the stream yet, but the
//SoundSource will wait until there is data
// as the stream is by default in the "don't stop at end" mode
source.Play(soundStream);
}
void UpdateSound()
{
// Try to keep 1/10 seconds of sound in the buffer, to avoid both
//dropouts and unnecessary latency
float targetLength = 1.0f / 10.0f;
float requiredLength = targetLength -
Bufferlength;//soundStream.BufferLength;
float w = 0;
if (requiredLength < 0.0f)
return;
uint numSamples = (uint)(soundStream.Frequency * requiredLength);
if (numSamples == 0)
return;
// Allocate a new buffer and fill it with a simple two-oscillator
//algorithm.The sound is over - amplified
// (distorted), clamped to the 16-bit range, and finally lowpass -
//filtered according to the coefficient
var newData = new short[numSamples];
for (int i = 0; i < numSamples; ++i)
{
float newValue = 0;
if (Beat == 0)
{
newValue = (float)(Amplitude * Math.Sin(Math.PI * Frequency * i / 44100D));
}
else
{
w = (float)(1D * Math.Sin(i * Math.PI * Beat / 44100D));
if (w < 0)
{
w = 0;
}
newValue = (float)(Amplitude * Math.Sin(Math.PI * Frequency * i / 44100D));
}
//accumulator = MathHelper.Lerp(accumulator, newValue, filter);
newData[i] = (short)newValue;
}
// Queue buffer to the stream for playback
soundStream.AddData(newData, 0, newData.Length);
}
}
}

Unity Android Google Play Services - Sending A String Message

I make a game for Android using Unity Engine and i use google play game services for multiplayer. I have a problem when i sending a string message to other player. I can send it but other player cant recived it.
Send Code:
public void SendMyUpdate(float posX, float posZ, Vector3 velocity, float rotY, float weapon, string opponentId)
{
DebugConsole.Log("OppenentSend " + opponentId);
bytesize = opponentId.Length * sizeof(byte);
_updateMessageLength = 26 + bytesize;
_updateMessage.Clear();
_updateMessage.Add(_protocolVersion);
_updateMessage.Add((byte)'U');
_updateMessage.AddRange(BitConverter.GetBytes(posX));
_updateMessage.AddRange(BitConverter.GetBytes(posZ));
_updateMessage.AddRange(BitConverter.GetBytes(velocity.x));
_updateMessage.AddRange(BitConverter.GetBytes(velocity.z));
_updateMessage.AddRange(BitConverter.GetBytes(rotY));
_updateMessage.AddRange(BitConverter.GetBytes(weapon));
//_updateMessage.AddRange(BitConverter.GetBytes(opponentHp));
_updateMessage.AddRange(System.Text.Encoding.UTF8.GetBytes(opponentId));
byte[] messageToSend = _updateMessage.ToArray();
PlayGamesPlatform.Instance.RealTime.SendMessageToAll(false, messageToSend);
}
Recived Code:
public void OnRealTimeMessageReceived(bool isReliable, string senderId, byte[] data)
{
// We'll be doing more with this later...
byte messageVersion = (byte)data[0];
// Let's figure out what type of message this is.
char messageType = (char)data[1];
if (messageType == 'U' && data.Length == _updateMessageLength)
{
float posX = BitConverter.ToSingle(data, 2);
float posZ = BitConverter.ToSingle(data, 6);
float velX = BitConverter.ToSingle(data, 10);
float velZ = BitConverter.ToSingle(data, 14);
float rotY = BitConverter.ToSingle(data, 18);
float weapon = BitConverter.ToSingle(data, 22);
//int opponentHp = BitConverter.ToInt16(data, 26);
string opponentId = System.Text.Encoding.UTF8.GetString(data);
// We'd better tell our GameController about this.
if (updateListener != null)
{
updateListener.UpdateReceived(senderId, posX, posZ, velX, velZ, rotY, weapon, opponentId);
DebugConsole.Log("OppenentRecived " + opponentId);
}
}
else if (messageType == 'F' && data.Length == _finishMessageLength)
{
// We received a final time!
float finalTime = System.BitConverter.ToSingle(data, 2);
//Debug.Log ("Player " + senderId + " has finished with a time of " + finalTime);
}
This got this code from
https://www.raywenderlich.com/87042/creating-cross-platform-multi-player-game-unity-part-2
You should remember to add an index of where the converter should find the byte range
ie: string opponentId = System.Text.Encoding.UTF8.GetString(data, int index);

Categories