概要

このドキュメントでは、Cocos2dランタイムの使用方法について説明します。ランタイムの言語はC++とObjective-Cです。書き出したJSONファイルを読み込んでシーンで再生する方法の例を説明します。

C++Objective-C の両方を使用しているため、このランタイムに呼び出すファイルは拡張子が .mm である必要があります。 .m ファイルの名前を .mm に変更するだけで動作します。

ランタイムを取得する

ランタイムをCreatureのGame Runtimesウィンドウから直接ダウンロードするか、リポジトリ(こちら)から取得することができます。

ヘッダインクルード

次のヘッダーを含める必要があります:

#include "CreatureModule.h"
#import "CCreatureRender.h"

読み込みと初期化

dragonTest.jsonと呼ばれるエクスポートされたドラゴンのアニメーションファイルがあるとしましょう。character-dragon.pngと呼ばれる対応するテクスチャアトラスもあると仮定します。 最初にファイルアセットを読み込むことから始めます。

NSString * jsonPath = [[NSBundle mainBundle] pathForResource:@"dragonTest" ofType:@"json"];
std::string realPath([jsonPath UTF8String]);

CCTexture * inputTexture = [CCTexture textureWithFile:@"character-dragon.png"];

CreatureModule::CreatureLoadDataPacket json_data;
CreatureModule::LoadCreatureJSONData(filename, json_data);

上のコードはJSONデータをディスクからメモリに読み込みます。次に、これらの読み込まれたアセットを利用できる実際のオブジェクトを作成しましょう:

auto cur_creature = std::shared_ptr<CreatureModule::Creature>(new CreatureModule::Creature(json_data));

creature_manager = new CreatureModule::CreatureManager(cur_creature);
creature_manager->CreateAnimation(json_data, "default");
creature_manager->CreateAnimation(json_data, "second");    

上記の例では、JSONファイルに2つのアニメーションクリップがあります: defaultsecondです。従って、creature_managerオブジェクトから2つのアニメーションを作成して再生できるようにする必要があります。

読み込みが完了したので、再生用のアクティブなアニメーションを設定できます:

creature_manager->SetActiveAnimationName("default");

これにより、現在アクティブなアニメーションとしてdefaultが設定されます。 キャラクターアニメーションをレンダリングするオブジェクトを作成します:

creature_render = [[CCreatureRender alloc] initWithData:creature_manager andTexture:inputTexture];
creature_render.scale = 12;
creature_render.position = CGPointMake(300, 100);

最後に、シーンにオブジェクトを追加します:

[self addChild:creature_render];

これで、あなたのキャラクターをCocos2dに統合する基本的な手順が完了しました!

完全なコードサンプル

以下は完全なコードレイアウトです。ほとんどのコードは、デフォルトのCocos2dXプロジェクトスターターテンプレートから生成されています。ほとんどの作業を行う loadModel () メソッドに注意してください:

CCLOG(@"Loading Creature");

NSString * jsonPath = [[NSBundle mainBundle] pathForResource:@"dragonTest" ofType:@"json"];
std::string realPath([jsonPath UTF8String]);

CCTexture * inputTexture = [CCTexture textureWithFile:@"character-dragon.png"];

// Load Creature
CreatureModule::CreatureLoadDataPacket json_data;
CreatureModule::LoadCreatureJSONData(realPath, json_data);

auto cur_creature = std::shared_ptr<CreatureModule::Creature>(new CreatureModule::Creature(json_data));
creature_manager = new CreatureModule::CreatureManager(cur_creature);

// Create and load the animations
auto new_animation_1 = std::shared_ptr<CreatureModule::CreatureAnimation>(
                                                                          new CreatureModule::CreatureAnimation(json_data,
                                                                                                                "default"));

creature_manager->AddAnimation(new_animation_1);
creature_manager->SetActiveAnimationName("default");
creature_manager->SetIsPlaying(true);
creature_manager->SetTimeScale(82.0);

creature_render = [[CCreatureRender alloc] initWithData:creature_manager andTexture:inputTexture];
creature_render.scale = 12;
creature_render.position = CGPointMake(300, 100);

[self addChild:creature_render];

カスタム時間/フレーム範囲

現在アクティブなアニメーションのカスタム時間/フレーム範囲を設定できます。再生を10〜20のフレーム範囲に制限したい場合は、次の操作を行います:

creature_manager->SetUseCustomTimeRange(true);
creature_manager->SetCustomTimeRange(10, 20);

アニメーションブレンディング

2つのアニメーションクリップをブレンドするには、次の手順を実行します:

creature_manager->SetBlending(true);
creature_manager->SetBlendingAnimations("default", "second");
creature_manager->SetBlendingFactor(0.5); // 0 to 1 blends between the 2 clips

ボーンの位置を変更する

場合によっては、キャラクターのボーンの位置を直接変更する必要があります。例えば、ボーンの位置をラグドール物理のスプリング/ジョイントに接続されたいくつかの剛体に従わせることができます。独自のカスタム要件に合わせてボーンの位置を設定する必要がある場合は、次の操作を行う必要があります。まず、カスタムボーンオーバーライドメソッドを記述します。yにあるボーンをある量だけ置き換える例を次に示します:

// This is an example of how you can use a callback function to modify the position of the bones
// on your character. In this example, we will displace all the bones by a fixed amount in y.
void
HelloWorld::bonesModifyCallback(std::unordered_map<std::string, meshBone *>& bones_map)
{
    for(auto& bone_data : bones_map)
    {
        auto cur_bone = bone_data.second;
        auto cur_start_pos = cur_bone->getWorldStartPt();
        auto cur_end_pos = cur_bone->getWorldEndPt();
    
        cur_start_pos.y -= 5;
        cur_end_pos.y -= 5;
    
        cur_bone->setWorldStartPt(cur_start_pos);
        cur_bone->setWorldEndPt(cur_end_pos);
    }
}

また、CreatureManagerにカスタムボーン修正コールバックを使用するために次のように伝える必要があります:

// Example of how to register a callback function to modify the bones
std::function<void (std::unordered_map<std::string, meshBone *>&) > cur_callback =
    std::bind(&HelloWorld::bonesModifyCallback, this, std::placeholders::_1);
creature_manager_2->SetBonesOverrideCallback(cur_callback);

キャラクターのインスタンス化とメモリ

キャラクターの複数コピー(例:2体のドラゴン)をインスタンス化する必要がある場合は、以下のようにアニメーションを作成する必要があります:

// Create and load the animations
auto new_animation_1 = std::shared_ptr<CreatureModule::CreatureAnimation>(
                                                                        new CreatureModule::CreatureAnimation(json_data,
                                                                                              "default"));

auto new_animation_2 = std::shared_ptr<CreatureModule::CreatureAnimation>(
                                                                          new CreatureModule::CreatureAnimation(json_data,
                                                                                                                "pose2"));

その後、新しいCreatureオブジェクト、新しいCreatureManagerオブジェクト、および新しいCreatureRendererオブジェクトを作成する必要があります。作成したアニメーションを、新しく作成したCreatureManagerオブジェクトに次のように追加します:

// Second creature instancing example. This shows you how to load a second creature.
// Because both the first and second creature share animation data, you end up
// saving memory.
auto creature_2 = std::shared_ptr<CreatureModule::Creature>(new CreatureModule::Creature(json_data));

CreatureModule::CreatureManager * creature_manager_2 = new CreatureModule::CreatureManager(creature_2);
creature_manager_2->AddAnimation(new_animation_1);
creature_manager_2->AddAnimation(new_animation_2);
creature_manager_2->SetActiveAnimationName("pose2");
creature_manager_2->SetIsPlaying(true);
creature_manager_2->SetUseCustomTimeRange(true);
creature_manager_2->SetCustomTimeRange(10, 60);

auto creature_renderer_2 = CreatureRenderer::Renderer::create(creature_manager_2,
                                                             CCTextureCache::getInstance()->addImage("character-dragon.png"));
creature_renderer_2->setColor(cocos2d::Color3B(255, 255, 255));
creature_renderer_2->setScale(30.0);
creature_renderer_2->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y - 200));

this->addChild(creature_renderer_2, 1);

この例と前の例との違いは、最初にアニメーションが作成され、それぞれのCreatureManagersに追加されることです。これは、アニメーションに割り当てられたメモリ(最もエクスペンシブなもの)が標準の場所に格納されていることを意味します。複数のCreatureManagerオブジェクトは、CreatureAnimationオブジェクトの共有プールからアニメーションを追加します。

ポイントキャッシュによる再生パフォーマンスの高速化

ポーズエンジンのコストを支払わずに再生アニメーションのスピードを上げたい場合は、特定のアニメーションでポイントキャッシュを有効にすることができます。

ポイントキャッシングは本質的にアニメーションの頂点を保存し、再生がポーズエンジンをバイパスできるようにします。非常に複雑なスケルトンと変形を伴うキャラクタリグは、ポイントキャッシングによって大きな利益を得ます。

特定のアニメーションでポイントキャッシングを有効にするには、次のようにします:

my_creature_manager->MakePointCache("myAnimationName");

これがキャッシュの作成に必要なすべてです。キャッシュはキャラクターではなく、アニメーションに固有のものであることに注意してください。つまり、複数のキャラクターをインスタンス化した場合、そのアニメーションの単一キャッシュのコストのみを支払うことになります。これにより、メモリ節約と再生パフォーマンスの高速化を実現できます