how i can remove lagging in my unity android game? - android

I am adroid proggrammer,because of many object in scene my game has lagging
i have theory for remove lagging in my game.
if i can control rendering in unity i can remove lagging.
using UnityEngine;
using System.Collections;
public class Enemy : MonoBehaviour {
void Update(){
void Start(){
GetComponent<Renderer>().enabled = false;
}
object2 = GameObject.Find("TR");
var distance = Vector3.Distance(gameObject.transform.position, object2.transform.position);
print (distance);
if(distance <= 80){
GetComponent<Renderer>().enabled = true;
}
}
}
Don't work.how can i have boolean render that when have collision will render
else remove.
i want have zone that all object in my zone rendered and allthing outside do not render.
void OnTriggerEnter(Collider collision)
{
if(collision.gameObject.tag == "zone")
{
GetComponent<Renderer>().enabled = true;
}
else{
GetComponent<Renderer>().enabled = false;
}
don't work
void OnTriggerEnter(Collider collision)
{
if(collision.gameObject.tag == "zone")
{
gameObject.SetActive(false);
}
else{
gameObject.SetActive(true);
}

This is either implemented in Unity or implementing it is a bad idea because raycasts are expensive and you need a lot of them. Try finding other problems which cause lagging in your game, disable feature by feature and write how many frames you have, this will get you best overview of what's the problem. Look online which methods are expensive (Instantiating, Destroy, try merging all models you have, smaller amount of shaders, fast shaders, less textures to load, FindGameObjectByName (or tag...)).

Here you will find a great document about optimization. It's preapared for mobile devices but i hope you will find what you need: Unity Optimization Guide for x86 Android

I would recommend having your blue blobs in an object pool, and the ones leaving your screen getting disabled.
You know your position and you know the position of the objects in the pool, you can math your distance in one direction, for instance behind you and disable after x amount.
Raycasting or collisions are abundant.
On your terrain generation scripts, check for disabled pool objects and if one exist, it should be put ahead in the level and repositioned or w/e logic you have there.
Don't instantiate and destroy unless you really need it, do it on level-load instead of on the fly.
(It's expensive.)
There's some really good tutorials on the unity page, have a look there.
They cover things like endless-runners.

Related

Unity3D : Raycast Issues on Android Build

I'm using Unity 3D for developing 3D desfense game.
I made a monster that can take agro from intruders of map, making them occupied while being vulnerable to other attacks. I wanted to make monster can be moved when it's touched once.
Process: touch the monster → touch the destination → monster moves to the destination
I wanted my monster to move through the entire map, but can take intruder's agro
only when they're on the road. I'm currently using Raycast to make this happen, and I'm stuck.
It works just fine on Unity, but when it's on a build and played on the phone, monster can't recognizes the touch or can't recognizes the point where I touched.
if (IsClickMonster)
{
if (Input.GetMouseButtonDown(0))
{
Ray MoveClick = cam.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(MoveClick, out ClickedPosition, float.MaxValue, whatCanbeClickedOn) && ClickedPosition.collider.gameObject.CompareTag("monster") == false)
{
Debug.Log("Monster is Moving!");
clickEffect.transform.position = new Vector3(ClickedPosition.point.x, ClickedPosition.point.y + 1.0f, ClickedPosition.point.z);
StopCoroutine("MonsterMove");
IsMoving = true;
StartCoroutine("MonsterMove");
}
else
{
clickEffect.SetActive(false);
StopCoroutine("MonsterMove");
IsClickMonster = false;
return;
}
}
}
else
{
return;
}
↑ Picture of Moving the Skull Soldier. White dot(clickEffect) is where Player touched(ClickedPosition).
Physics.Raycast(MoveClick, out ClickedPosition, float.MaxValue, whatCanbeClickedOn)
Even though I'm using the "whatCanbeClickedOn" layermask, I wonder what can I do to avoid this from happening on mobile build.
In my experience with android, when something doesnt work well in android could be either you have some error or warning on execution that did not trigger on unity just by chance or maybe the phone is not capable of handling the game like it moves too many polygons or lights and it cant handle it well then starts making odd things, try checking the warnings in unity and see if any error appears too of course, thats my best bet

Improve Frame rate on too many UI Images - Unity UI

In my single page, there were so many textures those I require to render before I was just facing problem in just screen opening but this I was able to resolve this suggestion:
OnBecomeVisible for Canvas UI Objects
Here is the actual code that I used for this purpose:
public void OnValueChangeRefreshCards (Vector2 valueChange)
{
elapsedYDist += valueChange.y;
if (elapsedYDist > 3f) {
elapsedYDist = 0f;
for (int i = 0; i < GameConstants.TOTAL_ROSE_COUNT; i++) {
Card card = roseList [i].GetComponent<Card> ();
if (RendererExtensions.IsVisibleFrom (card.MyRectTransform, Camera.main))
card.roseImage.enabled = true;
else
card.roseImage.enabled = false;
}
}
}
But now I started too much framerate lose related issue so even scrolling of page become really difficult for me.
Please check the attached video for more clearance about the issue, I was facing.
NameThatRose - Low Frame Rate
Please give me some suggestions for next improvements.
EDIT: Here are my profiler output.
Detailed Deep Profiler
Overview Deep Profiler
You can try few things to find out whats causing the low fps.
Use profiler to deep profile to find out which UI call is taking more time. Like what I did here.
As Image inherits from UIMaskableGraphics, it calls MaskableGraphics.OnEnable() every frame for every image in your list. This takes up time which you can see here:
I believe your OnValueChanged method is called every frame this would only multiply the enable/disable iterations and its processing time. You can limit the call by some time, processing 4 times a second for example.
float timeSinceLastUpdate = 0;
void Update()
{
timeSinceLastUpdate += Time.deltaTime;
}
public void OnValueChangeRefreshCards (Vector2 valueChange)
{
if(timeSinceLastUpdate < 0.25f)
{
return;
}
timeSinceLastUpdate = 0;
// do your stuff here...
}
You have 250+ images to process every frame which is a big deal for older Android devices, again as MaskableGraphics.OnEnable() call can be the culprit. You can avoid changing the state if it is required:
if (RendererExtensions.IsVisibleFrom (card.MyRectTransform, Camera.main))
{
if(!card.roseImage.enalbed)
card.roseImage.enabled = true;
}
else
{
if(card.roseImage.enalbed)
card.roseImage.enabled = false;
}
Furthermore, following are some helpful links to optimize UI in Unity:
Some of the best optimization tips for Unity UI
Tantzy Games
Gemserk
Other UI Optimization Techniques and Tips
A guide to optimizing Unity UI
UPDATE:
The following blog provides more information about UI rendering:
Making the UI Backend Faster
Hope this helps :)

Face detection + 3d model in android

I am using Camera.Face to detect face and min3D to load 3d models.
I want to let the model move with face, but it is not working well.
#Override
public void updateScene() {
if (mFaces == null) {
animeModel.position().x = animeModel.position().y = animeModel
.position().z = 0;
return;
}
for (Face face : mFaces) {
if (face == null) {
continue;
}
animeModel.position().x = face.rect.centerX();
animeModel.position().y = face.rect.centerY();
}
}
Is that model's coordinate and rectangle's coordinate are different systems?
(world coordinates to screen coordinates or something?)
How to solve this?
UPDATE:
I have try to get model's coordinate and face's coordinate.
These two value are totally different.
How to convert face.rect.centerX() to animeModel.position().x?
Here is an article all about how a face tracking demo was developed:
http://www.smallscreendesign.com/2011/02/07/about-face-detection-on-android-%E2%80%93-part-1/
That app is also available on the Play store. Part 1 of the above article has some performance metrics on recognition time. It looks like it may take up to two seconds or more to detect a face.
You could use the code in that article to do your prototyping. You may discover that face detection doesn't happen fast or often enough to track a face in realtime.
Here is the documentation for face tracking on the Android Developer site:
http://developer.android.com/reference/android/hardware/Camera.Face.html
UPDATE:
Check out this library: https://code.google.com/p/asmlib-opencv/

Keeping track of features in successive frames in OpenCV

I have written a program that uses goodFeaturesToTrack and calcOpticalFlowPyrLK to track features from frame to frame. The program reliably works and can estimate the optical flow in the preview image on an Android camera from the previous frame. Here's some snippets that describe the general process:
goodFeaturesToTrack(grayFrame, corners, MAX_CORNERS, quality_level,
min_distance, cv::noArray(), eig_block_size, use_harris, 0.06);
...
if (first_time == true) {
first_time = false;
old_corners = corners;
safe_corners = corners;
mLastImage = grayFrame;
} else {
if (old_corners.size() > 0 && corners.size() > 0) {
safe_corners = corners;
calcOpticalFlowPyrLK(mLastImage, grayFrame, old_corners, corners,
status, error, Size(21, 21), 5,
TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30,
0.01));
} else {
//no features found, so let's start over.
first_time = true;
}
}
The code above runs over and over again in a loop where a new preview frame is grabbed at each iteration. Safe_corners, old_corners, and corners are all arrays of class vector < Point2f > . The above code works great.
Now, for each feature that I've identified, I'd like to be able to assign some information about the feature... number of times found, maybe a descriptor of the feature, who knows... My first approach to doing this was:
class Feature: public Point2f {
private:
//things about a feature that I want to track
public:
//getters and fetchers and of course:
Feature() {
Point2f();
}
Feature(float a, float b) {
Point2f(a,b);
}
}
Next, all of my outputArrays are changed from vector < Point2f > to vector < Feature > which in my own twisted world ought to work because Feature is defined to be a descendent class of Point2f. Polymorphism applied, I can't imagine any good reason why this should puke on me unless I did something else horribly wrong.
Here's the error message I get.
OpenCV Error: Assertion failed (func != 0) in void cv::Mat::convertTo(cv::OutputArray, int, double, double) const, file /home/reports/ci/slave50-SDK/opencv/modules/core/src/convert.cpp, line 1095
So, my question to the forum is do the OpenCV functions truly require a Point2f vector or will a descendant class of Point2f work just as well? Next step would be to get gdb working with mobile code on an the Android phone and seeing more precisely where it crashes, however I don't want to go down that road if my approach is fundamentally flawed.
Alternatively, if a feature is tracked across multiple frames using the approach above, does the address in memory for each point change?
Thanks in advance.
The short answer is YES, OpenCV functions do require std::vector<cv::Point2f> as arguments.
Note that the vectors contain cv::Point2f objects themselves, not pointers to cv::Point2f, so there is no polymorphic behavior.
Additionally, having your Feature inherit from cv::Point2f is probably not an ideal solution. It would be simpler to use composition in this case, not to mention modeling the correct relationship (Feature has-a cv::Point2f).
Relying on an object's location in memory is also probably not a good idea. Rather, read up on your data structure of choice.
I'm just getting into OpenCV myself so can't address that aspect of the code but your problem might be a bug in your code that results in an uninitialized base class (at least not initialized as you might expect). Your code should look like this:
Feature()
: Point2f()
{
}
Feature(float a, float b)
: Point2f(a,b)
{
}
Your implementation creates two temporary Point2f objects in the constructor. Those temporary objects do not initialize the Feature object's Point2f base class and those temporary objects are destroyed at the end of the constructor.

How to collide objects with high speed in Unity

I try to create game for Android and I have problem with high speed objects, they don't wanna to collide.
I have Sphere with Sphere Collider and Bouncy material, and RigidBody with this param (Gravity=false, Interpolate=Interpolate, Collision Detection = Continuous Dynamic)
Also I have 3 walls with Box Collider and Bouncy material.
This is my code for Sphere
function IncreaseBallVelocity() {
rigidbody.velocity *= 1.05;
}
function Awake () {
rigidbody.AddForce(4, 4, 0, ForceMode.Impulse);
InvokeRepeating("IncreaseBallVelocity", 2, 2);
}
In project Settings I set: "Min Penetration For Penalty Force"=0.001, "Solver Interation Count"=50
When I play on the start it work fine (it bounces) but when speed go to high, Sphere just passes the wall.
Can anyone help me?
Thanks.
Edited
var hit : RaycastHit;
var mainGameScript : MainGame;
var particles_splash : GameObject;
function Awake () {
rigidbody.AddForce(4, 4, 0, ForceMode.Impulse);
InvokeRepeating("IncreaseBallVelocity", 2, 2);
}
function Update() {
if (rigidbody.SweepTest(transform.forward, hit, 0.5))
Debug.Log(hit.distance + "mts distance to obstacle");
if(transform.position.y < -3) {
mainGameScript.GameOver();
//Application.LoadLevel("Menu");
}
}
function IncreaseBallVelocity() {
rigidbody.velocity *= 1.05;
}
function OnCollisionEnter(collision : Collision) {
Instantiate(particles_splash, transform.position, transform.rotation);
}
EDITED added more info
Fixed Timestep = 0.02 Maximum Allowed Tir = 0.333
There is no difference between running the game in editor player and on Android
No. It looks OK when I set 0.01
My Paddle is Box Collider without Rigidbody, walls are the same
There are all in same layer (when speed is normal it all works) value in PhysicsManager are the default (same like in image) exept "Solver Interation Co..." = 50
No. When I change speed it pass other wall
I am using standard cube but I expand/shrink it to fit my screen and other objects, when I expand wall more then it's OK it bouncing
No. It's simple project simple example from Video http://www.youtube.com/watch?v=edfd1HJmKPY
I don't use gravity
See:
Similar SO Question
A community script that uses ray tracing to help manage fast objects
UnityAnswers post leading to the script in (2)
You could also try changing the fixed time step for physics. The smaller this value, the more times Unity calculates the physics of a scene. But be warned, making this value too small, say <= 0.005, will likely result in an unstable game, especially on a portable device.
The script above is best for bullets or small objects. You can manually force rigid body collisions tests:
public class example : MonoBehaviour {
public RaycastHit hit;
void Update() {
if (rigidbody.SweepTest(transform.forward, out hit, 10))
Debug.Log(hit.distance + "mts distance to obstacle");
}
}
I think the main problem is the manipulation of Rigidbody's velocity. I would try the following to solve the problem.
Redesign your code to ensure that IncreaseBallVelocity and every other manipulation of Rigidbody is called within FixedUpdate. Check that there are no other manipulations to Transform.position.
Try to replace setting velocity directly by using AddForce or similar methods so the physics engine has a higher chance to calculate all dependencies.
If there are more items (main player character, ...) involved related to the physics calculation, ensure that their code runs in FixedUpdate too.
Another point I stumbled upon were meshes that are scaled very much. Having a GameObject with scale <= 0.01 or >= 100 has definitely a negative impact on physics calculation. According to the docs and this Unity forum entry from one of the gurus you should avoid Transform.scale values != 1
Still not happy? OK then the next test is starting with high velocities but no acceleration. At this phase we want to know, if the high velocity itself or the acceleration is to blame for the problem. It would be interesting to know the velocities' values at which the physics engine starts to fail - please post them so that we can compare them.
EDIT: Some more things to investigate
6.7 m/sec does not sound that much so that I guess there is a special reason or a combination of reasons why things go wrong.
Is your Maximum Allowed Timestep high enough? For testing I suggest 5 to 10x Fixed Timestep. Note that this might kill the frame rate but that can be dfixed later.
Is there any difference between running the game in editor player and on Android?
Did you notice any drops in frame rate because of the 0.01 FixedTimestep? This would indicate that the physics engine might be in trouble.
Could it be that there are static colliders (objects having a collider but no Rigidbody) that are moved around or manipulated otherwise? This would cause heavy recalculations within PhysX.
What about the layers: Are all walls on the same layer resp. are the involved layers are configured appropriately in collision detection matrix?
Does the no-bounce effect always happen at the same wall? If so, can you just copy the 1st wall and put it in place of the second one to see if there is something wrong with this specific wall.
If not to much effort, I would try to set up some standard cubes as walls just to be sure that transform.scale is not to blame for it (I made really bad experience with this).
Do you manipulate gravity or TimeManager.timeScale from within a script?
BTW: are you using gravity? (Should be no problem just

Categories

Resources