Is calling a script in unityscript slow? - android

My enemy script is linked to a prefab and being instantiated by my main script.
It kills enemies in a random order (I am jumping on them and some are not dying, not what I want).
(what I am trying to achieve is an enemy to die when I jump on its head and play a death animation.
So from this enemy script I call the other script jump <-- which is linked to my player script and get the jump Boolean value. Could the processing of jump be to slow? I need help
I tried everything)
it works but only on certain enemies any ideas why? Thanks community.
Can anyone help me find a better method?
Could someone help me maybe find if the Players y => an amount to change jump var on the enemy
Just had a perfect run, whats wrong with this its working then not then it is partly working
If I add audio, it doesn't work.
#pragma strict
var enemy : GameObject;
var speed : float = 1.0;
var enemanim : Animator;
var isdying : boolean = false;
private var other : main;
var playerhit: boolean = false;
function Start () {
other = GameObject.FindWithTag("Player").GetComponent("main");
this.transform.position.x = 8.325;
this.transform.position.y = -1.3;
enemanim = GetComponent(Animator);
enemanim.SetFloat("isdead",0);
}
function OnCollisionEnter2D(coll: Collision2D) {
if(coll.gameObject.CompareTag("distroy")){
Destroy(enemy.gameObject);
}
if(coll.gameObject.CompareTag("Player")){
playerhit=true;
}
}
function Update () {
if(other.jumped === true && playerhit==true){ *****the jumped i need
enemanim.SetFloat("isdead",1);
}
}
function FixedUpdate(){
this.transform.Translate(Vector3(Input.GetAxis("Horizontal") * speed * Time.deltaTime, 0, 0));
this.rigidbody2D.velocity = Vector2(-5,0);
}

if(other.jumped === true && playerhit==true)
Is wrong.
It should be:
if(other.jumped == true && playerhit==true)
All 3 languages used by Unity, C#, UnityScript, and Boo, are compiled into the same IL byte code at the end. However, there are cases where UnityScript has some overhead as Unity does things in the background. One of these is that it does wrapping of access to members of built-in struct-properties like transform.position.
I prefer C#, I think it is better.

Related

cocos2dx Multi touch and touch

everyone! I have trouble with combination in one scene multi touch and one touch with. So let me describe my problem step by step.
I use cocos2dx( for android ), So I have scene, on this scene I add layer Pan Zoom Layer for scroll and zoom. next, I add new layer(Game Layer) on PanZoomLayer. I need catch click on Game Layer(on this layer located my game things) I try to do so, using pattern observer,I have done PanZoom Layer by "Subject" my Game Layer - "Observer", and in PanZoomLayer Have created enum EVENTS, and struct touchEvent
enum EVENTS{
EVENT_ONCE_CLICK,
EVENT_MOVE,
ANOTHER,
};
struct touchEvent {
EVENTS eventName;
};
and created in class PanZoomLayer field m_events :
std::stack<EVENTS> m_events;
and on onTouchesBegan add such code
if (_touches.size() == 1) {
m_events.push(EVENTS::EVENT_ONCE_CLICK);
}
else {
m_events.push(EVENTS::ANOTHER);
}
in onTouchesMoved add such code in branch if _touches.size() == 1:
Vec2 curTouchPosition = Director::getInstance()->convertToGL(touch->getLocationInView());
Vec2 prevTouchPosition = Director::getInstance()->convertToGL(touch->getPreviousLocationInView());
Vec2 deltaPosition = curTouchPosition - prevTouchPosition;
float pos = curTouchPosition.distance(prevTouchPosition);
if (fabs(pos) < 0.5f) {
m_events.push(EVENTS::EVENT_ONCE_CLICK);
}
else {
m_events.push(EVENTS::ANOTHER);
}
an onTouchesEnded, add such code :
if (m_events.empty())
return;
EVENTS ev = m_events.top();
while (!m_events.empty()) {
m_events.pop();
}
if (ev == EVENTS::EVENT_ONCE_CLICK) {
// MessageBox("once click", "title");
Touch *touch = (Touch *)_touches.at(0);
Vec2 position = touch->getLocation();
notifyClick(position);
}
where notifyClick :
std::shared_ptr<CSceneSession> sessionShared = m_session.lock();
if (sessionShared)
sessionShared->clickOnScene(point);
So I enter in game cycle : game scene -> transition on menu scene -> game scene...... in start it great work, but after some time ( on difference devices - different time) game begin strange behavior : buggy,
Could you help me please? Thanks for any idea and suggestions.
I Solved my problem in the following way: I remove scheduleUpdateForTarget in method onEnter and remove unscheduleAllForTarget in method onExit and remove method update.
Thank you for your attention!

as3 worker thread communication issue on android

i am having issues with speed of communication between workers in AS3 coding for AIR for android. my test device is a Galaxy S2 (android 4.0.4) and i am developing in flashdevelop using AIR18.0.
first things first.
i tried the good old AMF serialisation copying via shared object. i was getting smack average 49 calculations/second on the physics engine (the secondary thread) with a stable 60FPS on main thread. had to crank it up over to over 300 dynamic objects to get any noticeable slowdown.
all went well, so i started the on-device testing and that is when shit started to go sideways. i was getting less than 1.5 steps/s.
started to dig a bit deeper, write a shitton of code to check what the hell is so slow and i found that looking at shared objects was kinda like watching other people watching paint dry.
at this point i started to get deeper into researching. i found that there are a number of people already complaining about the speed of message channels (found not much on shared objects, "developers" status quo i guess). so i decided to go the lowest i could using shared bytearrays and mutexes. (i skipped over condition since i don't particularly want any of my threads to pause).
cranked up the desktop debugger i was getting 115-ish calculations/s and over 350 calculations/s with direct callback (the debugger did throw the exception, wasn't designed for that kind of continuous processing i guess.. anywho..). shared bytearray and mutexes was as advertised, faster than the orgasm of my ex girlfriend.
i do the debugging on the S2 and behold, i get 3.4 calculations/s with 200 dynamic objects.
so.. concurrency on mobile was pretty much done for me. then i thought i do a little test with no communication whatsoever. same scene, physics doing a more than acceptable 40 calculations/s and graphics running at the expected 60FPS...
so, my bluntly evident question:
WHAT the FAPPING FIREFLY is going on?
here is my Com code:
package CCom
{
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2World;
import flash.concurrent.Condition;
import flash.concurrent.Mutex;
import flash.utils.ByteArray;
import Grx.DickbutImage;
import Phx.PhxMain;
/**
* shared and executed across all threads.
* provides access to mutex and binary data.
*
* #author szeredai akos
*/
public class CComCore
{
//===============================================================================================//
public static var positionData:ByteArray = new ByteArray();
public static var positionMutex:Mutex = new Mutex();
public static var creationData:ByteArray = new ByteArray();
public static var creationMutex:Mutex = new Mutex();
public static var debugData:ByteArray = new ByteArray();
public static var debugMutex:Mutex = new Mutex();
//===============================================================================================//
public function CComCore()
{
positionData.shareable = true;
creationData.shareable = true;
debugData.shareable = true;
}
//===============================================================================================//
public static function encodePositions(w:b2World):void
{
var ud:Object;
positionMutex.lock();
positionData.position = 0;
for (var b:b2Body = w.GetBodyList(); b; b = b.GetNext())
{
ud = b.GetUserData();
if (ud && ud.serial)
{
positionMutex.lock();
positionData.writeInt(ud.serial); // serial
positionData.writeBoolean(b.IsAwake); // active state
positionData.writeInt(b.GetType()) // 0-static 1-kinematic 2-dynamic
positionData.writeDouble(b.GetPosition().x / PhxMain.SCALE); // x
positionData.writeDouble(b.GetPosition().y / PhxMain.SCALE); // y
positionData.writeDouble(b.GetAngle()); // r in radians
}
}
positionData.length = positionData.position;
positionMutex.unlock();
}
//===============================================================================================//
public static function decodeToAry(ar:Vector.<DickbutImage>):void
{
var index:int;
var rot:Number = 0;
positionData.position = 0;
while (positionData.bytesAvailable > 0)
{
//positionMutex.lock();
index = positionData.readInt();
positionData.readBoolean();
positionData.readInt();
ar[index].x -= (ar[index].x - positionData.readDouble()) / 10;
ar[index].y -= (ar[index].y - positionData.readDouble()) / 10;
ar[index].rotation = positionData.readDouble();
//positionMutex.unlock();
}
}
//===============================================================================================//
}
}
(disregard the lowpass filter on the position y-=(y-x)/c)
so.
please note that having the mutex only on the parsing of the physics does increase performance by about 20% while having minimal impact on the framerate of the main thread. this leads me to believe that the problem does not lie in the writing and reading of the data per say but in the speed at which that data is made available for a second thread. i mean,.. those are bytearray ops, it's only natural that it is fast. i did check the speed by simply dumping the remote thread into the main, and the speed is still sound. hell,.. it gets acceptable even on the S2 without dumping the extra calculations.
ps: i did try release version too.
if no one has a viable solution (besides a .2-.4s buffer, and the obvious single thread) i do want to hear about wanky workarounds or at least the specific source of the problem.
thx in advance
Think I found the issue.
As always things are more complex than one initially thinks.
Timer events, as well as set interval and timeout are all limited to 60fps. The timer does execute on time as long as the app is idle at that particular point or IMMEDIATELY after it is free to execute and the delay has passed. But the delay, obviously, can't be shorter than 15-ish (and its less on desktop, I guess). Shouldn't be a problem, right?
However.
If that piece of code manipulates shared objects the timer suddenly decides to shit himself and look at it for those 15ms regardless if it had its idle time or not.
Anyhow, the thing is that there is an buggy interaction between shared objects, workers, timer events and the adobe imposed 60FPS limitation.
The workaround is quite simple. Have the timer on some massive delay of like 5000ms and do like 5000 loops within the callback of the timer event. Obviously, the next timer event won't fire until the 5000loop is completed but most importantly it also won't add that monumental delay.
Another weird thing that came up is the greedy ownership of mutexes during the 5000loop so the usage of flash.concurrent.Condition is a must.
The good thing is that the performance boost is there and its impressive.
The downside is that the entire physics thing is now intimately locked to the framerate of the main thread (or whatever contraption the main game loop consists of), but hey. 60Fps is good enough, I guess.
Zi MuleTrex-Condition thing for those interested:
package CCom
{
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2World;
import flash.concurrent.Condition;
import flash.concurrent.Mutex;
import flash.utils.ByteArray;
import Grx.DickbutImage;
import Phx.PhxMain;
/**
* shared and executed across all threads.
* provides access to mutex and binary data.
*
* #author szeredai akos
*/
public class CComCore
{
//===============================================================================================//
public static var positionData:ByteArray = new ByteArray();
public static var positionMutex:Mutex = new Mutex();
public static var positionCondition:Condition = new Condition(positionMutex);
public static var creationData:ByteArray = new ByteArray();
public static var creationMutex:Mutex = new Mutex();
public static var debugData:ByteArray = new ByteArray();
public static var debugMutex:Mutex = new Mutex();
//===============================================================================================//
public function CComCore()
{
positionData.shareable = true;
creationData.shareable = true;
debugData.shareable = true;
}
//===============================================================================================//
public static function encodePositions(w:b2World):void
{
var ud:Object;
positionData.position = 0;
positionMutex.lock();
for (var b:b2Body = w.GetBodyList(); b; b = b.GetNext())
{
ud = b.GetUserData();
if (ud && ud.serial)
{
positionData.writeBoolean(b.IsAwake); // active state
positionData.writeInt(ud.serial); // serial
positionData.writeInt(b.GetType()) // 0-static 1-kinematic 2-dynamic
positionData.writeDouble(b.GetPosition().x / PhxMain.SCALE); // x
positionData.writeDouble(b.GetPosition().y / PhxMain.SCALE); // y
positionData.writeDouble(b.GetAngle()); // r in radians
}
}
positionData.writeBoolean(false);
positionCondition.wait();
}
//===============================================================================================//
public static function decodeToAry(ar:Vector.<DickbutImage>):void
{
var index:int;
var rot:Number = 0;
positionMutex.lock();
positionData.position = 0;
while (positionData.bytesAvailable > 0 && positionData.readBoolean())
{
//positionMutex.lock();
index = positionData.readInt();
positionData.readInt();
ar[index].x = positionData.readDouble();
ar[index].y = positionData.readDouble();
ar[index].rotation = positionData.readDouble();
//positionMutex.unlock();
}
positionCondition.notify();
positionMutex.unlock();
}
//===============================================================================================//
}
}
Sync will become a lot more complex as more channels and byteArrays start to pop up.

How to translate OnMouse events to Touch phases for Android?

I'm stuck to a rather simple solution, with my script translated run in Android with Unity3d. I'm having a gameObject "Cube" and a js script attached for rotation.
Also I' m having a script "ClickButton.js" attached to a GUI.Texture. Everything works o.k. in Unity Player, but I want to translate this script to be used by touches in Android devices. Problem is I can't do it, although I have read the Unity documentation.
Here is the code snippet:
//This script is attached on a GUI.Texture acting as a button
var normalTexture : Texture2D;
var hoverTexture : Texture2D;
function Update(){
for (var i = 0; i < Input.touchCount; ++i) {
if (Input.GetTouch(i).phase == TouchPhase.Began)
var rotate = Input.GetTouch(i);
rotate == doRotate();
}
}
}
function OnMouseEnter(){
guiTexture.texture = hoverTexture;
}
function OnMouseExit(){
guiTexture.texture = normalTexture;
}
function OnMouseDown(){
var runScriptRotate : GameObject[] = GameObject.FindGameObjectsWithTag("Marker");
for(var doRotation : GameObject in runScriptRotate){
var scriptRT : doRotate = doRotation.GetComponent(doRotate);
if(scriptRT){
// access the function "doRotation" on a script named "doRotate" on gameObject "Cube"
doRotate.doRotation();
}
}
}
Can somebody, be kind enough to edit this code script, so to make it work on Android by touching? Thank you all in advance!
Why don't you just copy the contents of OnMouseDown()? Basically touch is the same as mouse down on android devices, isn't it?
if(Input.touchCount > 0){
if(Input.GetTouch(0).phase == TouchPhase.Began){
var runScriptRotate : GameObject[] = GameObject.FindGameObjectsWithTag("Marker");
for(var doRotation : GameObject in runScriptRotate){
var scriptRT : doRotate = doRotation.GetComponent(doRotate);
if(scriptRT){
// access the function "doRotation" on a script named "doRotate" on gameObject "Cube"
doRotate.doRotation();
}
}
}
}

Unity WebPlayer to Android Build Issues

I am new to Unity so a well stepped out answer would be nice. I am trying to make a dice roller on an Android platform. I was following this very well put together tutorial http://games.ucla.edu/resource/unity-1-beginner-tutorial-dice-making-pt-1/ (There is a second part too)
The problem is that it was made for a Web Player. If I try to build it for Android I get two particular errors.
I have two simple scripts with one error associated with each one.
SideTrigger.js - Error: BCE0019: 'currentValue' is not a member of 'UnityEngine.Component'.
public var faceValue = 0;
function OnTriggerEnter( other : Collider ) {
var dieGameObject = GameObject.Find("SixSidedDie");
var dieValueComponent = dieGameObject.GetComponent("DieValue");
dieValueComponent.currentValue = faceValue; //ERROR HERE
Debug.Log("Die1: " + faceValue);
}
DieValue.js - Error: BCE0019: 'text' is not a member of 'UnityEngine.Component'.
public var currentValue = 0;
function Update () {
var dieTextGameObject = GameObject.Find("DieText");
var textMeshComponent = dieTextGameObject.GetComponent("TextMesh");
textMeshComponent.text = currentValue.ToString(); //ERROR HERE
}
I'm assume it's purely a syntactical issue, but I can't seem to find a solution.
GetComponent using string is not recommended due to performance reasons, it is documented here.
It is better to use this:
var dieValueComponent : DieValue = dieGameObject.GetComponent(DieValue)
Or this:
var dieValueComponent : DieValue = dieGameObject.GetComponent.<DieValue>()
See if that works.

BitmapData lock and unlock not working on android

The following code will erase a bitmap (brush akk droplet) from another bitmap (akka
The code works great on PC and pretty ok performacewise.
When i test it on more android devices, it doesn't work. No matter if is a high end device or a slower one. I've made some tests and found out the problem is lock() and unlock() functions from BitmapData. It simply doesn't update the image on device, only once.
I've tried to remove them, but the then it lags alot. Also the performace drop is noticeable on PC too.
Does anyone know a solution, where am I doing wrong?
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.geom.Rectangle;
var m:BitmapData = new water_pattern;
var b:BitmapData = new droplet;
var bm:Bitmap = new Bitmap(m);
var bla = new blabla();
addChild(bla);
bla.addChild(bm);
function p($x,$y){
var refPoint = new Point($x-b.width/2,$y-b.height/2);
for(var i=0;i<b.width;i++)
for(var j=0;j<b.height;j++)
{
var a:uint = (b.getPixel32(i,j)>> 24) & 0xFF;
a=0xFF-a;
var tp:uint = m.getPixel32(refPoint.x+i,refPoint.y+j);
var tp_trans:uint = (tp >> 24)&0xFF;
if(tp_trans>a){
tp=(tp&0x00FFFFFF)|(a<<24);
m.setPixel32(refPoint.x+i,refPoint.y+j,tp);
}
}
//for(var k=0;k<10000000;k++){};
}
var k=1;
var md = function(e)
{
m.lock();
p(bm.mouseX,bm.mouseY);
m.unlock();
};
bla.addEventListener(MouseEvent.MOUSE_DOWN,function(e)
{
bla.addEventListener(Event.EXIT_FRAME,md);
});
bla.addEventListener(MouseEvent.MOUSE_UP,function(e)
{
bla.removeEventListener(Event.EXIT_FRAME,md);
});
I've reworked the code :
public function draw($x, $y)
{
var refPoint = new Point($x - brush.width / 2, $y - brush.height / 2);
var r:Rectangle = new Rectangle(refPoint.x, refPoint.y, brush.width, brush.height);
var pv:Vector.<uint> = pattern.getVector(r);
var bv:Vector.<uint> = brush.getVector(brush.rect);
for (var i = 0; i < bv.length; i++)
{
var a:uint = (bv[i]>>24) &0xFF;
a = 0xFF - a;
var tp:uint = pv[i];
var tp_trans:uint = (tp >> 24) & 0xFF;
// trace(a.toString(16) + " vs " + tp_trans.toString(16));
if (tp_trans > a)
{
tp = (tp & 0x00FFFFFF) | (a << 24);
// trace("??>" + tp);
pv[i] = tp;
}
}
pattern.setVector(r, pv);
}
Now it works, but still it is pretty slow on device. That before i saw Jeff Ward's comment, so i changed it to render mode on CPU. It works fast.
The big problem is in CPU mode the game is very slow compared to GPU. Yet this script is fast on CPU but unusable slow on GPU.
So I've tried again the first code and surprise. It works. Jeff Ward, thank you, you're a genius.
Now the question remains is why? Can someone please explain?
For your original question, sometimes GPU mode doesn't pick up changes into the underlying bitmapdata. Try any one of these operations after your unlock() to 'hint' that it should re-upload the bitmap data:
bm.filters = [];
bm.bitmapData = m;
bm.alpha = 0.98+Math.random()*0.02;
But as you found, uploading bitmapdata can be slow. To clarify GPU/direct render modes:
In GPU mode, changing any pixel in a Bitmap requires a re-upload of the full bitmap, so it's the size of Bitmap that's the limiting factor. In direct mode, it blits only the portions of the screen that have been updated. So I'd guess some parts of the game change a lot of the screen at once (slow in direct mode), whereas this effect changes a large bitmap, but only a little bit at a time (slow in GPU mode).
You have to get creative to maximize your performance wrt GPUs:
In GPU mode, split the effect into many bitmaps, and only change as few as possible for any given frame. (medium effort)
Use Starling GPU-accelerated framework and Starling filters (GPU shaders) to achieve your effect (effort depends on how much you have invested in your game already), see a couple of examples

Categories

Resources