Why aren't I getting One Bullet One Hit? - android

In my collision detection code, bullets are deactivated once they have been involved in a collision:
for(int j = 0; j < enemies.size(); j++){
//check for collision
if(bullets[i].isActive() && bullets[i].getSprite().collidesWith(enemies.get(j).getSprite())){
//remove bullet
removeBullet(i); //bullet is deactivated here, .isActive() will return false
if(enemies.get(j).damage(1)){
// --snip--
}
break;
}
}
The only place bullets are deactivated is in this section of code. The only place they are activated is when they are created.
Despite this a bullet will inflict damage multiple times. removeBullet() triggers an explosion animation, and this plays multiple times. What could be going wrong?
Update
Here's removeBullet()
private void removeBullet(int i){
if(bullets[i] == null) return;
bullets[i].deactivate();
makeSmallExplosion(bullets[i].getSprite().getX(),bullets[i].getSprite().getY());
bulletPool.recyclePoolItem(bullets[i]);
bullets[i] = null;
}

More than one thread may be running? Alternatively it might not be a problem with removing the bullet. But there are multiple bullets at that position and/or enemies?

Ah AndEngine; I'm actually a Mod on the forum :)
I've wrote this blog post about object pools in case you need to check the way you've implemented yours:
http://c0deattack.wordpress.com/category/programming/andengine/
I wonder if you're recycling the bullet properly?

Related

Unity without using Update

I'm developing a small game currently that involves players guessing. The player can additionally use special cards, that, for example, reveal one letter/add time he/she has for guessing and so on. Game is divided into two scenes -> one with shop, inventory, player profile etc the second one is strictly for guessing.
Currently, almost everything runs in the update in the second scene, but I really hate it. I was trying to rewrite everything into coroutines BUT the problem is that it seems impossible to use cards inside IEnumerator (or maybe I'm doing something wrong?).
For example, a simple countdown. If it's in Update I can easily influence the time with using cards(f.e. add 30 seconds). In the case of IEnumetor, I can't (Or maybe better, I don't know how to do it).
int secondsForGuess = 30;
IEnumerator Countdown () {
int counter = secondsForGuess;
while (counter > 0) {
yield return new WaitForSeconds (1);
counter--;
}
}
Any general suggestion how to do it without using Update will be greatly appreciated :D
If I understand your question right, you want to be able to increase the counter from the outside of the routine. So simply make it a field in the class so anyone can increase or decrease it:
const int secondsForGuess = 30;
private int counter;
public void AddToCounter(int seconds)
{
counter += seconds;
}
private IEnumerator Countdown ()
{
counter = secondsForGuess;
while (counter > 0) {
yield return new WaitForSeconds (1);
counter--;
}
// Do something when finsihed
}
Also just in case: Make sure to somewhere start the routine using StartCoroutine.

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 :)

Libgdx for loop lag

I have problems with my game. The game runs ok until the time where I have to reposition the objects, which happens every frame. For example here I have to reposition some parked cars (around 6 cars on each side of the road), the cars are constantly moving down in the screen, then they reset and reposition at the top again. I have used Poolable to save resources. However, the game is still very jumpy when it comes to running these lines of code. Is there any way I could improve the code to prevent lag? Maybe a new thread? If so how would be the right way of creating a new thread and updating it every frame.
private void updateParkedVehicles(float delta){
for (int i = 0; i < parkedCarLeft1Array.size; i++){
parkedCarLeft1Array.get(i).update(delta);
for (int c = 0; c < parkedCarLeft1Array.size; c++){
if (c != i){
if (Intersector.overlaps(parkedCarLeft1Array.get(i).bounds, parkedCarLeft1Array.get(c).bounds)){
parkedCarLeft1Array.get(i).reset();
}
}
}
}
for (int i = 0; i < parkedCarRight1Array.size; i++){
parkedCarRight1Array.get(i).update(delta);
for (int c = 0; c < parkedCarRight1Array.size; c++){
if (c != i){
if (Intersector.overlaps(parkedCarRight1Array.get(i).bounds, parkedCarRight1Array.get(c).bounds)){parkedCarRight1Array.get(i).reset();
}
}
}
}
}
One way to handle items in your game is through the use of the Scene2d.
Scene2D allows you to step out from having to move yourself the items. Instead you give them instructions (as a director would) if and when you need to move them instead of having to handle yourselve every frame update.
in a nutshell, to add an Action you would do this:
if(SomeCondition){
MoveToAction moveCar = new MoveToAction();
moveCar.setPosition(anX,anY);
moveCar.setDuration(aDuration);
myCarActor.addAction(moveCar);
}
That way, the only thing you need to check for is the occurence of the event and you call your function to move the car only once (when the event occurs).
LibGdx will take care of updating your actor each frame.
The only thing you will need to do in your loop is to check the collision. If they occur then you will assign a new Action to your actor.
Another thing to keep in Mind, if you use Scene2D is that you can use the Camera. This means that if you need to scroll, instead of moving each item, you simply move the camera (which has all the convenience method you need to zoom etc).
For more information on Scene2D check out: https://github.com/libgdx/libgdx/wiki/scene2d
For more information specifically on Actions check this out:
https://github.com/libgdx/libgdx/wiki/Scene2d#actions
Hope it helps.
It seems to me that the problem is with double looping through arrays --> O(n^2) complexity!!
It's not clear for me why you need to check overlapping of each car with each car except this car if "the cars are constantly moving down in the screen, then they reset and reposition at the top again". For the described behaviour the simplest way would be to check is the current y position is less that 0 and rest position if so:
for (Car car : parkedCarLeft1Array){
car.update(delta);
if (car.getY <= 0) {
car.reset();
}
}
I assume that you update car position in update() method.

Unity 2D collisions with prefabs not working on phone

I'm having a bit of a problem with OnTriggerEnter when I'm using my mobile as a test device.
I have some touch code that successfully lets me drag objects around the screen.
I am then having the objects collide with other objects on the screen.
This was working perfectly until I turned the objects into prefabs. ( I'm needing to do this as the objects are being randomly generated at runtime)
Now, I can still move the objects around the screen but they no longer collide with the other objects, which are also prefabs. It does however still work fine when running it on my laptop in the unity editor.
All my objects have colliders on them with trigger checked, and the moving objects have rigidbodies.
On trigger enter code
public void OnTriggerEnter(Collider other)
{
Debug.Log ("here");
Debug.Log(this.gameObject.tag +"is this");
Debug.Log(other.gameObject.tag + "is other");
if (this.gameObject.tag == other.gameObject.tag)
{
Debug.Log("here2)");
Reftomanager.miniGameScore++;
Reftomanager.updateScore();
Destroy(this.gameObject);
}
}
touch code
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
switch(touch.phase)
{
case TouchPhase.Began:
Ray ray = Camera.main.ScreenPointToRay (touch.position);
if (Physics.Raycast(ray,out hit))
{
thisObject = hit.collider.gameObject;
touchPos = Camera.main.ScreenToWorldPoint (touch.position);
if(thisObject.name!="circle")
{
draggingMode = true;
}
}
break;
case TouchPhase.Moved:
if (draggingMode)
{
touchPos = Camera.main.ScreenToWorldPoint (touch.position);
newCentre = touchPos;
thisObject.transform.position = touchPos;
}
break;
case TouchPhase.Ended:
draggingMode = false;
break;
}
}
}
I'm completely stumped so any help would be amazing.
Thanks
Just got this same error recently. I suggest using
If(other.gameObject.CompareTag ("YourTagName"))
Also if you recently added a tag or edited any tags, I found that unity has a bug where your tags will not register on your android build unless you restart unity.
GL.
Since your using 3D colliders, is it possible that the position you are assigning them is different? Touch.position is a Vector2, which means ScreenToWorldPoint would be using 0 for z. If you are using a Vector3 with a z value other than 0 to get the world point in the editor (Standalone Input), it could get you a different value even if x and y are the same.
Another possibility is that there is a platform specific error happening somewhere else in the code, upon object instantiate. Your movement code would still work fine, if it isn't in the same Monobehavior.
If you have an Android, you can use Android Monitor with the Unity tag to check for error messages.

How to set objects on a androidH runner game

I am trying to develop a android runner game for school purpose..
I am still new to this and please I need your assistance..
You guys can view my CS5flash file at >>> http://www.filedropper.com/test_37
The obstacles and coins are on random. But the obstacles and coins are overlapping each other.. Which is very bad for a runner game because it looks very bad and the gameplay gets very very complicated.
How can i fix it??. Is there any way to fix it?.
And i am also thinking if I can set the obstacles and coins to a specific area (not on random). So the game will be more oganized and the gameplay won't be complicated. Which i still don't know -_-.
But i still prefer it on random. So guys please help me fix it..
You will need to change the way you are adding the coins and obstacles! I suggest using a timer for each. Atm you are adding a ton of them on every frame, calculating overlaps would use too much resources! and put them in an array or better a vector! i would reccomend using an object Pool aswell!
so limit the amout of coins and hurdles that can be present, like 5 or so. then remove them from the array/vector when they are offscreen or collected! then when you add new stuff you can check against the array/vector what the allowed values are!
when you got your Array you can pass it to the randomRange() function and exlcude those values!
would look somthing like this! not testet!!
function randomRange (min:Number, max:Number, exclude:Array = null):int
{
var val:int = (min + Math.random() * (max - min)) >> 0;
if (exclude)
{
for (var i:int = 0; i < exclude; i++)
{
while ((val < exclude[i].x + exclude[i].width) && (val > exclude[i].x))
{
val = (min + Math.random() * (max - min)) >> 0;
}
}
}
return val;
}
Its still quite exspensive performance wise. but with only a few object you should be fine

Categories

Resources