2014년 5월 15일 목요일

unity3d script : Object들을 담는 자료 구조(.Net Generic collections)

리스트를 사용하고자 할때 Array, ArrayList, HashTable은 사용하지 말도록…

대신, .Net의 gerneric collections 이나 단순 배열을 사용하도록 합니다.
 - 선언시 자료형을 지정하기 떄문에 명시적 형변환이 필요 없습니다.
 - ArrayList보다 빠릅니다.

리스트를 쓰고자 할 때는 List<Type>,
해쉬 테이블을 사용하고자 할 때는  Dictionary<KeyType,ValueType>


사용하기 전에 아래와 같은 선언이 필요합니다.
using System.Collections.Generic


리스트 사용 방법

//Define a list using C#
List<int> myList = new List<int>();
List<SomeClass> anotherList = new List<SomeClass>();

//Add element to a list
myList.Add(someValue);

//Add multiple elements to a list
myList.AddRange(someListOrArrayOfValues);

//Clear all elements
myList.Clear();

//Insert into a list
myList.Insert(1, someValue);

//Insert multiple elements
myList.InsertRange(1, someListOrArrayOfValues);

//Remove a specific value
myList.Remove(someValue);

//Remove at a specific index
myList.RemoveAt(1);

//Find an index of an element
var index = myList.IndexOf(someValue);

//Find an index of something using a function in Javascript
var index = anotherList.FindIndex(function(entry) entry.someValue == something);

//Turn a list into an array
var myArray = myList.ToArray();

//Find an index of something using a function in C#
var index = anotherList.FindIndex((entry) => entry.someValue == something)

//Get the number of items in the list
var itemCount = myList.Count


딕셔너리 사용 방법

//Define a string to int dictionary in C#
Dictionary<string, int> myDic = new Dictionary<string, int>();

//Define a dictionary of GameObject to a class in C#
Dictionary<GameObject, SomeClass> anotherDic = new Dictionary<GameObject, SomeClass>();

//Add an element to a dictionary
myDic["Something"] = someIntValue;

//Get a value from a dictionary
var someValue = myDic["Something"];

//Get a complex value and change one of its properties
anotherDic[gameObject].someProperty = someValue;

//Check if a value exists
if(myDic.ContainsKey("Something")) { }

//Remove an element from a dictionary
myDic.Remove("Something');

//Run through all of the keys in the dictionary JS
for(var key : String in myDic.Keys) { }

//Run through all of the values in the dictionary in C#
foreach(int value in myDic.Values) { }

//Clear all elements
myDic.Clear();

//Get the number of items in the dictionary
var count = myDic.Count;

unity3d script : 특정 script에 access하는 방법

자신의 오브젝트에 존재하는 스크립트를 찾아 access하는 방법

GetComponent<TargetScriptName>().someVariable = someValue;
GetComponent<TargetScriptName>().SomeMethod();


다른 오브젝트를 통해 access하는 방법
void OnTriggerEnter(Collider other)
{
      other.GetComponent<TargetScriptName>().someVariable = someValue;
}

void OnCollisionEnter(Collision collision)
{
      collision.GetComponent<TargetScriptName>().someVariable = someValue;
}


이름이나 태그를 통해 스크립트 찾아내는 방법
GameObject.FindWithTag 함수나 GameObject.Find 함수를 사용

targetScript = GameObject.Find("someObjectName").GetComponent<TargetScriptName>();


모든 child오브젝트에서의 특정 스크립트를 얻어내고자 할 경우...

for(var t : Transform in transform)
{
     target = t.GetComponent(TargetScriptName);
     target.DoSomething();
     target.someVariable = someValue;
}

unity3d script : 특정 범위에 포함되는 충돌체에 데미지 주기

float radius = 10.0F;
float power = 1000.0F;

Collider[] colliders = Physics.OverlapSphere (_transform.position, radius);

foreach(Collider col in colliders)
{
if(col.rigidbody)
{
  if(col.rigidbody != gameObject.rigidbody)
  {
       col.rigidbody.AddExplosionForce (power, _transform.position, radius);
  }
}
}


2014년 4월 3일 목요일

android wear sdk preview

모든 설명은 여기에..
https://developer.android.com/intl/ko/wear/preview/start.html


sdk api level 19부터 지원
시뮬레이터로 square, round 2가지 시계를 가지고 놀수 있다.
(아직 한글 안됨)

developer preview signing을 받아 폰에 Android Preview app을 설치하여
폰과 시계(시율레이터 ㅡㅡ;)를 연동하는 테스트를 해볼수 있음.

폰과 시계는 adb 포트포워딩을 통해 tcp연결함.
adb -d forward tcp:5601 tcp:5601

기본기능이 Notification을 통한 waer의 알림과 wear에서의 조작이 폰에 연동되는 기능임.
https://developer.android.com/intl/ko/wear/notifications/creating.html

아직 별거 없지만. 기능들이 점점 늘어날꺼라 기대함.

android용 ffmpeg shared library만들때

생성되는 라이브러리 이름이 libxxxx.so.<version> 라는 형식으로 생성되는경우
이는 안드로이드 빌드 시스템과 호환이 안된다.
아래와 같이 configure 파일의 부분을 찾아 바꿔줘야 함


SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'

이것을

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'

이렇게


android.mk에는 아래처럼 추가해주고

LOCAL_PATH := $(call my-dir)

# --------------------------------------------------------------------------------------------------------
include $(CLEAR_VARS)
LOCAL_MODULE := libavcodec
LOCAL_SRC_FILES := ./ffmpeg2.0.1/armv7-a/lib/libavcodec-55.so
include $(PREBUILT_SHARED_LIBRARY)

# --------------------------------------------------------------------------------------------------------
include $(CLEAR_VARS)
LOCAL_MODULE := libavformat
LOCAL_SRC_FILES := ./ffmpeg2.0.1/armv7-a/lib/libavformat-55.so
include $(PREBUILT_SHARED_LIBRARY)

# --------------------------------------------------------------------------------------------------------
include $(CLEAR_VARS)
LOCAL_MODULE := libswresample
LOCAL_SRC_FILES := ./ffmpeg2.0.1/armv7-a/lib/libswresample-0.so
include $(PREBUILT_SHARED_LIBRARY)

# --------------------------------------------------------------------------------------------------------
include $(CLEAR_VARS)
LOCAL_MODULE := libswscale
LOCAL_SRC_FILES := ./ffmpeg2.0.1/armv7-a/lib/libswscale-2.so
include $(PREBUILT_SHARED_LIBRARY)

# --------------------------------------------------------------------------------------------------------
include $(CLEAR_VARS)
LOCAL_MODULE := libavfilter
LOCAL_SRC_FILES := ./ffmpeg2.0.1/armv7-a/lib/libavfilter-3.so
include $(PREBUILT_SHARED_LIBRARY)

# --------------------------------------------------------------------------------------------------------
include $(CLEAR_VARS)
LOCAL_MODULE := libavresample
LOCAL_SRC_FILES := ./ffmpeg2.0.1/armv7-a/lib/libavresample-1.so
include $(PREBUILT_SHARED_LIBRARY)

# --------------------------------------------------------------------------------------------------------
include $(CLEAR_VARS)
LOCAL_MODULE := libavutil
LOCAL_SRC_FILES := ./ffmpeg2.0.1/armv7-a/lib/libavutil-52.so
include $(PREBUILT_SHARED_LIBRARY)


# --------------------------------------------------------------------------------------------------------
include $(CLEAR_VARS)

LOCAL_MODULE    := MyNativeModuleName


LOCAL_CFLAGS := .....
LOCAL_CPPFLAGS := .....

LOCAL_C_INCLUDES :.....
LOCAL_SRC_FILES :.....


LOCAL_LDLIBS := .....
LOCAL_SHARED_LIBRARIES := libavcodec libavformat libswscale libavutil libswresample libavfilter libavresample libavutil


java쪽에서 아래와 같이  dependency에 순서에 맞게 라이브러리를 로딩합니다.

static
{
LOG.d(TAG, "Build.CPU_ABI : " + Build.CPU_ABI);

        System.loadLibrary("avutil-52");
        System.loadLibrary("avcodec-55");
        System.loadLibrary("avformat-55");
        System.loadLibrary("swresample-0");
        System.loadLibrary("swscale-2");
        System.loadLibrary("avresample-1");
        System.loadLibrary("avfilter-3");
        System.loadLibrary("MyNativeModuleName");

}


2014년 3월 9일 일요일

cocos2dx를 이용한 live wallpaper만들기

cocos2dx 안드로이드 프로젝트의 기본 main activity를 라이브웰 페이퍼 구성을 위해 아래와 같이 WallpaperService로 변경하는 것으로 구현이 가능합니다.
(cocos2d-x 2.x버전에서 테스트)

import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import org.cocos2dx.lib.Cocos2dxHelper;
import org.cocos2dx.lib.Cocos2dxHelper.Cocos2dxHelperListener;
import org.cocos2dx.lib.Cocos2dxRenderer;

import android.content.Context;
import android.content.SharedPreferences;
import android.opengl.GLSurfaceView.Renderer;
import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

public class WallpaperCocos2dxService extends WallpaperService
{

static
{
System.loadLibrary("cocos2dcpp");
}

@Override
public Engine onCreateEngine()
{
        return new Cocos2dxWallpaperEngine();
}

public class Cocos2dxWallpaperEngine extends Engine implements Cocos2dxHelperListener,
SharedPreferences.OnSharedPreferenceChangeListener
{

protected class WallpaperCocos2dxGLSurfaceView extends Cocos2dxGLSurfaceView 
{
            WallpaperCocos2dxGLSurfaceView(Context context) 
            {
                super(context);
            }

            @Override
            public SurfaceHolder getHolder() 
            {
                return getSurfaceHolder();
            }

            public void onDestroy() 
            {
                super.onDetachedFromWindow();
            }
}

protected class WallpaperCocos2dxRenderer extends Cocos2dxRenderer
{
// prevent the cocos2dxRenderer from calling nativeInit
@Override
public void onSurfaceCreated(final GL10 pGL10, final EGLConfig pEGLConfig)
{
}

@Override
public void onSurfaceChanged(final GL10 pGL10, final int pWidth, final int pHeight)
{
setScreenWidthAndHeight(pWidth, pHeight);
super.onSurfaceCreated(null, null);
}

}

private WallpaperCocos2dxGLSurfaceView m_WallpaperCocos2dxGLSurfaceView;
@Override
public void onCreate(SurfaceHolder surfaceHolder)
{
super.onCreate(surfaceHolder);
//setTouchEventsEnabled(true);
            m_WallpaperCocos2dxGLSurfaceView = new WallpaperCocos2dxGLSurfaceView(WallpaperCocos2dxService.this);
            m_WallpaperCocos2dxGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
            
            //mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer());
            
            setRenderer(getNewRenderer());
            Cocos2dxHelper.init(WallpaperCocos2dxService.this, this);
}

@Override
public void onVisibilityChanged(boolean visible)
{
            super.onVisibilityChanged(visible);
            if (visible) 
            {
                Cocos2dxHelper.onResume();
                m_WallpaperCocos2dxGLSurfaceView.onResume();
            } 
            else 
            {
                Cocos2dxHelper.onPause();
                m_WallpaperCocos2dxGLSurfaceView.onPause();            
            }
}

@Override
public void onDestroy()
{
            super.onDestroy();

            Cocos2dxHelper.end();

            m_WallpaperCocos2dxGLSurfaceView.onDestroy();
}

protected void setRenderer(Renderer renderer) 
{
            m_WallpaperCocos2dxGLSurfaceView.setCocos2dxRenderer((Cocos2dxRenderer) renderer);
}
   
Renderer getNewRenderer()
{
            Cocos2dxRenderer renderer = new WallpaperCocos2dxRenderer();
            return renderer;
}

@Override
public void showDialog(String pTitle, String pMessage)
{
// TODO Auto-generated method stub
}

@Override
public void showEditTextDialog(String pTitle, String pMessage, int pInputMode, int pInputFlag, int pReturnType, int pMaxLength)
{
}

@Override
public void runOnGLThread(Runnable pRunnable)
{
m_WallpaperCocos2dxGLSurfaceView.queueEvent(pRunnable);
}

@Override
public void onTouchEvent(MotionEvent event)
{
            m_WallpaperCocos2dxGLSurfaceView.onTouchEvent(event);
}

@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String sKey)
{

}
}

}

2014년 1월 25일 토요일

android ADB에서 미디어 스캐너 구동시키기..

adb shell에 들어가서..

am broadcast -a android.intent.action.MEDIA_MOUNTED -d file:///mnt/sdcard