万年素人からHackerへの道

万年素人がHackerになれるまで殴り書きするぜ。

CharacterControllerでの衝突判定 Unity

  • 衝突判定がたまにうまくいかないことがある

http://www.kanotype.net/blogwp/?p=50
↑こちらを参考にすると
・Collider同志では衝突イベントが発生しない
・両方のどっちかのオブジェクトは必ずKenematicではないRigidBodyコンポーネントを含んでいる必要がある
らしい。

CharacterControllerコンポーネントが適用された「Player」
→「Kinematicでないrigidbody」を適用している

「敵」にも
→「Kinematicでないrigidbody」を適用している
→「CapsuleCollider」を適用している

しかし、敵とPlayerがぶつかっても、「OnCollisionEnterメソッド」がなぜか反応しない!!



反応しないときは「OnControllerColliderHit」↓を使う
http://unity3d.com/support/documentation/ScriptReference/CharacterController.OnControllerColliderHit.html



OnTrigger〜の使い方 Unity

OnCollision〜でのApplyするもののイマイチわからなかった

  • ”アイテムの取得”や”銃弾”などに使う(ぶつかった衝撃で物体を動かしたくないとき)

■Player(プレイヤー)
◯Applyされているもの
・〜Collider(Triggerチェックなし)
・rigidbody
スクリプト:OnTrigger〜で判定


■Item(アイテム)
◯Applyされているもの
・〜Collider(Triggerチェックあり)
・rigidbody
スクリプト:OnCollision〜で判定


■上記2つの衝突時の結果
・Playerのスクリプト -> 動いた
・Itemのスクリプト -> 動かなかった



C#のオプション引数 Unity

C#は4.0からデフォルト引数(C#の正式名称はオプション引数(optional parameter))がつくらしいのだが、
UnityのC#ではないみたい。

void Hoge (string bar="foo") {}

よく忘れるMathfのメモ

Mathf.Sin(ラジアンでは"ない"角度);

http://unity3d.com/support/documentation/ScriptReference/Mathf.Sin.html

float rad = deg * Mathf.Deg2Rad;

http://unity3d.com/support/documentation/ScriptReference/Mathf.Deg2Rad.html
→Mathf.Deg2Rad(角度);って引数へ角度を入れがち

解像度に依存させない Unity

GUI.matrix = Matrix4x4.TRS (
	Vector3.zero,
	Quaternion.identity,
	new Vector3 (Screen.width / 320.0F, Screen.height / 420.0F, 1)
);

C#でかいてるので、JavaScriptはnew消すだけ?
横320x縦420がもともとのときはこうする。
比率でボタンサイズを決めてたらおかしくなる。


Mono Develop文字化け修正 Unity

3.4.1だとMono Developの文字が治らない
http://d.hatena.ne.jp/shu223/20110705/1310403782
→英語にする 文字化けするなら日本語にしないで十分

BlenderをノートPCでやるテンキー設定

http://blender.jp/modules/xoopsfaq/index.php?cat_id=2


フェードイン/アウトっぽいScene切り替え Unity

http://dl.dropbox.com/u/18252342/zominose.apk

  • ここで私が質問した結果を日本人向けへ展開


  • LoadTransition.cs
using UnityEngine;
using System.Collections;

// fades in a image ( use a white texture for just a color )
// loads the level.
// fades out the image.
public class LoadTransition : MonoBehaviour {
    public string levelIndexOrName = "0";
    public bool isIndex = true;
    public float fadeOutSeconds;
    public float fadeInSeconds;
    public int guiDepth = -10;
    public Texture image;
    public Color imageOpaqueColor = Color.white;
    public Color imageClearColor = new Color(1F, 1F, 1F, 0F);
    
    private float percentFadeInOrOut = 0F;
    private bool fadingIn = false;
    private float showingPercent {get {return fadingIn ? (1F - percentFadeInOrOut ) : percentFadeInOrOut;}}

    IEnumerator Fade( bool fade_in, float seconds ) {
        fadingIn = fade_in;
		percentFadeInOrOut = 0F;
        float startTime = Time.realtimeSinceStartup;
        do yield return null; while((percentFadeInOrOut= Mathf.Min ( (Time.realtimeSinceStartup - startTime) / fadeOutSeconds, 1F ) ) < 1F);
        yield break;
    } 

    IEnumerator Start() {
        DontDestroyOnLoad(gameObject);

        // fade out old scene
        yield return StartCoroutine(Fade(false, fadeOutSeconds));

        // let the gui render once at complete fade.
        yield return new WaitForEndOfFrame();
        // to be safe wait one more frame ( you can see if you need this next line or not )
        yield return null;

        // load the level
        if (isIndex) Application.LoadLevel(int.Parse(levelIndexOrName));
        else Application.LoadLevel(levelIndexOrName);
        // wait 2 frames for awake and start ( or more if you need )
        yield return null; yield return null; 

        // now fade in the newly loaded scene.
        yield return StartCoroutine(Fade(true, fadeInSeconds));
         
        // again wait a frame for gui to pickup
        yield return null;

        // and were done.
        Destroy(gameObject);
    }
    void OnGUI () {
        GUI.depth = guiDepth;
        if (image) {
            GUI.color = Color.Lerp(imageClearColor, imageOpaqueColor, showingPercent);
            GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), image);
        }
    }
    static LoadTransition InstantiateManually (float secondsFade, Texture image, Color color) {
        // make our game object with component.
        GameObject loaderGameObject = new GameObject("loadTransition", typeof(LoadTransition));
        LoadTransition loader = loaderGameObject.GetComponent<LoadTransition>();
        // laziness: just set in and out to the same.
        loader.fadeInSeconds = secondsFade;
        loader.fadeOutSeconds = secondsFade;

        if (image)
            loader.image = image; // only set image if its non null ( this could preserve default settings )
        // set in the color
        loader.imageOpaqueColor = color;
        loader.imageClearColor = color;
        // force alpha on opaque to be 1 and clear:0
        loader.imageOpaqueColor.a = 1F;
        loader.imageClearColor.a = 0F;
        return loader;
    }
    public static LoadTransition Load (string levelName, float secondsFade, Texture image, Color color) {
        LoadTransition loader = InstantiateManually(secondsFade, image, color);
        loader.isIndex = false;
        loader.levelIndexOrName = levelName;
        return loader;
    } 
    public static LoadTransition Load (int levelIndex, float secondsFade, Texture image, Color color) {
        LoadTransition loader = InstantiateManually(secondsFade, image, color);
        loader.isIndex = true;
        loader.levelIndexOrName = levelIndex.ToString();// or System.Convert
        return loader;
    }

    // runs until we've been destroyed.
    IEnumerator WaitUntilFinishedProc() {do yield return null; while(true);}

    // gets something you can wait on with yield return.
    public YieldInstruction WaitUntilFinished() {return StartCoroutine(WaitUntilFinishedProc());}
    
    // prefab use only. Instantiates the prefab but changes the level name
    public static LoadTransition InstantiateWithLevel (LoadTransition prefab, string levelName)  {
        LoadTransition loader = (LoadTransition)Instantiate(prefab);
        loader.isIndex = false;
        loader.levelIndexOrName = levelName;
		return loader;
    }
    public static LoadTransition InstantiateWithLevel (LoadTransition prefab, int levelIndex) {
        LoadTransition loader = (LoadTransition)Instantiate(prefab);
        loader.isIndex = true;
        loader.levelIndexOrName = levelIndex.ToString();// or System.Convert
		return loader;
    }
}

”LoadTransition.cs”ファイルへ↑のソースを貼ります

  • やり方

今まで「sceneName」をこのように呼んでたのを

Application.LoadLevel("sceneName");

public Texture SomeWhiteTexture;

変数宣言でSomeWhiteTexture(白テクスチャ)を宣言しておく。
インスペクタでテクスチャをApplyするの忘れないように。

LoadTransition.Load("sceneName", 1F, SomeWhiteTexture, Color.black); 

これで実際に呼びます。
「Load("シーン名", フェードインとアウトのそれぞれの時間, テクスチャ, 色); 」
Color.blackはColor.whiteとか別の色にしてもいいです。

数字だけのシーンなら

LoadTransition.Load(1, 1F, SomeWhiteTexture, Color.black); 

このように「"」を使わずに行けそう。

  • 未確認

"Now Loading..."みたいなやつを載せるときは
prefabを登録すれば行けそうだが・・・

LoadTransition.InstantiateWithLevel(prefab, "levelNameHere");